From 9c66ce662c076fc1f5e57c4e72126e41d56d0b80 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Tue, 6 Jan 2015 13:11:21 -0800 Subject: fsl-ch3/lowlevel: TZPC and TZASC programming to configure non-secure accesses This patch ensures that the TZPC (BP147) and TZASC-400 programming happens for LS2085A SoC only when the desired config flags are enabled and ensures that the TZPC programming is done to allow Non-secure (NS) + secure (S) transactions only for DCGF registers. The TZASC component is not present on LS2085A-Rev1, so the TZASC-400 config flag is turned OFF for now. Signed-off-by: Bhupesh Sharma Reviewed-by: York Sun --- include/configs/ls2085a_common.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 6fe032c9ff6..38984432b5a 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -13,6 +13,7 @@ #define CONFIG_FSL_LSCH3 #define CONFIG_LS2085A #define CONFIG_GICV3 +#define CONFIG_FSL_TZPC_BP147 /* Link Definitions */ #define CONFIG_SYS_TEXT_BASE 0x30001000 -- cgit v1.3.1 From 03e664d8f4065010ccb6c75648192200a832fd8b Mon Sep 17 00:00:00 2001 From: York Sun Date: Tue, 6 Jan 2015 13:18:50 -0800 Subject: driver/ddr/fsl: Add support for multiple DDR clocks Controller number is passed for function calls to support individual DDR clock, depending on SoC implementation. It is backward compatible with exising platforms. Multiple clocks have been verifyed on LS2085A emulator. Signed-off-by: York Sun --- drivers/ddr/fsl/arm_ddr_gen3.c | 2 +- drivers/ddr/fsl/ctrl_regs.c | 208 +++++++++++++++++--------------- drivers/ddr/fsl/ddr1_dimm_params.c | 18 +-- drivers/ddr/fsl/ddr2_dimm_params.c | 12 +- drivers/ddr/fsl/ddr3_dimm_params.c | 8 +- drivers/ddr/fsl/ddr4_dimm_params.c | 8 +- drivers/ddr/fsl/fsl_ddr_gen4.c | 2 +- drivers/ddr/fsl/lc_common_dimm_params.c | 27 +++-- drivers/ddr/fsl/main.c | 25 ++-- drivers/ddr/fsl/mpc85xx_ddr_gen3.c | 4 +- drivers/ddr/fsl/options.c | 6 +- drivers/ddr/fsl/util.c | 12 +- include/fsl_ddr.h | 15 ++- include/fsl_ddr_dimm_params.h | 2 +- 14 files changed, 190 insertions(+), 159 deletions(-) (limited to 'include') diff --git a/drivers/ddr/fsl/arm_ddr_gen3.c b/drivers/ddr/fsl/arm_ddr_gen3.c index c139da6da94..7160da4ec89 100644 --- a/drivers/ddr/fsl/arm_ddr_gen3.c +++ b/drivers/ddr/fsl/arm_ddr_gen3.c @@ -222,7 +222,7 @@ step2: bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK) >> SDRAM_CFG_DBW_SHIFT); timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 / - (get_ddr_freq(0) >> 20)) << 1; + (get_ddr_freq(ctrl_num) >> 20)) << 1; total_gb_size_per_controller >>= 4; /* shift down to gb size */ debug("total %d GB\n", total_gb_size_per_controller); debug("Need to wait up to %d * 10ms\n", timeout); diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index b3477f04b71..713c3ed7619 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -17,8 +17,6 @@ #include #include -unsigned int picos_to_mclk(unsigned int picos); - /* * Determine Rtt value. * @@ -78,10 +76,11 @@ static inline int fsl_ddr_get_rtt(void) * 16 for <= 2933MT/s * 18 for higher */ -static inline unsigned int compute_cas_write_latency(void) +static inline unsigned int compute_cas_write_latency( + const unsigned int ctrl_num) { unsigned int cwl; - const unsigned int mclk_ps = get_memory_clk_period_ps(); + const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); if (mclk_ps >= 1250) cwl = 9; else if (mclk_ps >= 1070) @@ -111,10 +110,11 @@ static inline unsigned int compute_cas_write_latency(void) * 11 if 0.935ns > tCK >= 0.833ns * 12 if 0.833ns > tCK >= 0.75ns */ -static inline unsigned int compute_cas_write_latency(void) +static inline unsigned int compute_cas_write_latency( + const unsigned int ctrl_num) { unsigned int cwl; - const unsigned int mclk_ps = get_memory_clk_period_ps(); + const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); if (mclk_ps >= 2500) cwl = 5; @@ -287,7 +287,8 @@ static inline int avoid_odt_overlap(const dimm_params_t *dimm_params) * Avoid writing for DDR I. The new PQ38 DDR controller * dreams up non-zero default values to be backwards compatible. */ -static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, +static void set_timing_cfg_0(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts, const dimm_params_t *dimm_params) { @@ -306,7 +307,7 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, /* Mode register set cycle time (tMRD). */ unsigned char tmrd_mclk; #if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3) - const unsigned int mclk_ps = get_memory_clk_period_ps(); + const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); #endif #ifdef CONFIG_SYS_FSL_DDR4 @@ -314,15 +315,15 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */ trwt_mclk = 2; twrt_mclk = 1; - act_pd_exit_mclk = picos_to_mclk(txp); + act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp); pre_pd_exit_mclk = act_pd_exit_mclk; /* * MRS_CYC = max(tMRD, tMOD) * tMRD = 8nCK, tMOD = max(24nCK, 15ns) */ - tmrd_mclk = max(24U, picos_to_mclk(15000)); + tmrd_mclk = max(24U, picos_to_mclk(ctrl_num, 15000)); #elif defined(CONFIG_SYS_FSL_DDR3) - unsigned int data_rate = get_ddr_freq(0); + unsigned int data_rate = get_ddr_freq(ctrl_num); int txp; unsigned int ip_rev; int odt_overlap; @@ -344,7 +345,8 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, * tMRD = 4nCK (8nCK for RDIMM) * tMOD = max(12nCK, 15ns) */ - tmrd_mclk = max((unsigned int)12, picos_to_mclk(15000)); + tmrd_mclk = max((unsigned int)12, + picos_to_mclk(ctrl_num, 15000)); } else { /* * MRS_CYC = tMRD @@ -388,7 +390,7 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, taxpd_mclk = 1; } else { /* act_pd_exit_mclk = tXARD, see above */ - act_pd_exit_mclk = picos_to_mclk(txp); + act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp); /* Mode register MR0[A12] is '1' - fast exit */ pre_pd_exit_mclk = act_pd_exit_mclk; taxpd_mclk = 1; @@ -424,11 +426,12 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, #endif /* !defined(CONFIG_SYS_FSL_DDR1) */ /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */ -static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm, - unsigned int cas_latency, - unsigned int additive_latency) +static void set_timing_cfg_3(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, + const memctl_options_t *popts, + const common_timing_params_t *common_dimm, + unsigned int cas_latency, + unsigned int additive_latency) { /* Extended precharge to activate interval (tRP) */ unsigned int ext_pretoact = 0; @@ -447,18 +450,18 @@ static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr, /* Control Adjust */ unsigned int cntl_adj = 0; - ext_pretoact = picos_to_mclk(common_dimm->trp_ps) >> 4; - ext_acttopre = picos_to_mclk(common_dimm->tras_ps) >> 4; - ext_acttorw = picos_to_mclk(common_dimm->trcd_ps) >> 4; + ext_pretoact = picos_to_mclk(ctrl_num, common_dimm->trp_ps) >> 4; + ext_acttopre = picos_to_mclk(ctrl_num, common_dimm->tras_ps) >> 4; + ext_acttorw = picos_to_mclk(ctrl_num, common_dimm->trcd_ps) >> 4; ext_caslat = (2 * cas_latency - 1) >> 4; ext_add_lat = additive_latency >> 4; #ifdef CONFIG_SYS_FSL_DDR4 - ext_refrec = (picos_to_mclk(common_dimm->trfc1_ps) - 8) >> 4; + ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8) >> 4; #else - ext_refrec = (picos_to_mclk(common_dimm->trfc_ps) - 8) >> 4; + ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8) >> 4; /* ext_wrrec only deals with 16 clock and above, or 14 with OTF */ #endif - ext_wrrec = (picos_to_mclk(common_dimm->twr_ps) + + ext_wrrec = (picos_to_mclk(ctrl_num, common_dimm->twr_ps) + (popts->otf_burst_chop_en ? 2 : 0)) >> 4; ddr->timing_cfg_3 = (0 @@ -475,10 +478,11 @@ static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr, } /* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */ -static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm, - unsigned int cas_latency) +static void set_timing_cfg_1(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, + const memctl_options_t *popts, + const common_timing_params_t *common_dimm, + unsigned int cas_latency) { /* Precharge-to-activate interval (tRP) */ unsigned char pretoact_mclk; @@ -510,9 +514,9 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, 1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0}; #endif - pretoact_mclk = picos_to_mclk(common_dimm->trp_ps); - acttopre_mclk = picos_to_mclk(common_dimm->tras_ps); - acttorw_mclk = picos_to_mclk(common_dimm->trcd_ps); + pretoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trp_ps); + acttopre_mclk = picos_to_mclk(ctrl_num, common_dimm->tras_ps); + acttorw_mclk = picos_to_mclk(ctrl_num, common_dimm->trcd_ps); /* * Translate CAS Latency to a DDR controller field value: @@ -547,19 +551,19 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, #endif #ifdef CONFIG_SYS_FSL_DDR4 - refrec_ctrl = picos_to_mclk(common_dimm->trfc1_ps) - 8; - wrrec_mclk = picos_to_mclk(common_dimm->twr_ps); - acttoact_mclk = max(picos_to_mclk(common_dimm->trrds_ps), 4U); - wrtord_mclk = max(2U, picos_to_mclk(2500)); + refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8; + wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); + acttoact_mclk = max(picos_to_mclk(ctrl_num, common_dimm->trrds_ps), 4U); + wrtord_mclk = max(2U, picos_to_mclk(ctrl_num, 2500)); if ((wrrec_mclk < 1) || (wrrec_mclk > 24)) printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk); else wrrec_mclk = wrrec_table[wrrec_mclk - 1]; #else - refrec_ctrl = picos_to_mclk(common_dimm->trfc_ps) - 8; - wrrec_mclk = picos_to_mclk(common_dimm->twr_ps); - acttoact_mclk = picos_to_mclk(common_dimm->trrd_ps); - wrtord_mclk = picos_to_mclk(common_dimm->twtr_ps); + refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8; + wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); + acttoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trrd_ps); + wrtord_mclk = picos_to_mclk(ctrl_num, common_dimm->twtr_ps); if ((wrrec_mclk < 1) || (wrrec_mclk > 16)) printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk); else @@ -602,11 +606,12 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, } /* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */ -static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm, - unsigned int cas_latency, - unsigned int additive_latency) +static void set_timing_cfg_2(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, + const memctl_options_t *popts, + const common_timing_params_t *common_dimm, + unsigned int cas_latency, + unsigned int additive_latency) { /* Additive latency */ unsigned char add_lat_mclk; @@ -623,7 +628,7 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr, /* Window for four activates (tFAW) */ unsigned short four_act; #ifdef CONFIG_SYS_FSL_DDR3 - const unsigned int mclk_ps = get_memory_clk_period_ps(); + const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); #endif /* FIXME add check that this must be less than acttorw_mclk */ @@ -641,13 +646,13 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr, #elif defined(CONFIG_SYS_FSL_DDR2) wr_lat = cas_latency - 1; #else - wr_lat = compute_cas_write_latency(); + wr_lat = compute_cas_write_latency(ctrl_num); #endif #ifdef CONFIG_SYS_FSL_DDR4 - rd_to_pre = picos_to_mclk(7500); + rd_to_pre = picos_to_mclk(ctrl_num, 7500); #else - rd_to_pre = picos_to_mclk(common_dimm->trtp_ps); + rd_to_pre = picos_to_mclk(ctrl_num, common_dimm->trtp_ps); #endif /* * JEDEC has some min requirements for tRTP @@ -665,19 +670,20 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr, wr_data_delay = popts->write_data_delay; #ifdef CONFIG_SYS_FSL_DDR4 cpo = 0; - cke_pls = max(3U, picos_to_mclk(5000)); + cke_pls = max(3U, picos_to_mclk(ctrl_num, 5000)); #elif defined(CONFIG_SYS_FSL_DDR3) /* * cke pulse = max(3nCK, 7.5ns) for DDR3-800 * max(3nCK, 5.625ns) for DDR3-1066, 1333 * max(3nCK, 5ns) for DDR3-1600, 1866, 2133 */ - cke_pls = max(3U, picos_to_mclk(mclk_ps > 1870 ? 7500 : - (mclk_ps > 1245 ? 5625 : 5000))); + cke_pls = max(3U, picos_to_mclk(ctrl_num, mclk_ps > 1870 ? 7500 : + (mclk_ps > 1245 ? 5625 : 5000))); #else cke_pls = FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR; #endif - four_act = picos_to_mclk(popts->tfaw_window_four_activates_ps); + four_act = picos_to_mclk(ctrl_num, + popts->tfaw_window_four_activates_ps); ddr->timing_cfg_2 = (0 | ((add_lat_mclk & 0xf) << 28) @@ -818,7 +824,8 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, } /* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */ -static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, +static void set_ddr_sdram_cfg_2(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts, const unsigned int unq_mrs_en) { @@ -865,7 +872,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, #endif #if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7) - slow = get_ddr_freq(0) < 1249000000; + slow = get_ddr_freq(ctrl_num) < 1249000000; #endif if (popts->registered_dimm_en) { @@ -915,7 +922,8 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr, #ifdef CONFIG_SYS_FSL_DDR4 /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ -static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, +static void set_ddr_sdram_mode_2(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts, const common_timing_params_t *common_dimm, const unsigned int unq_mrs_en) @@ -926,10 +934,10 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, unsigned int wr_crc = 0; /* Disable */ unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */ unsigned int srt = 0; /* self-refresh temerature, normal range */ - unsigned int cwl = compute_cas_write_latency() - 9; + unsigned int cwl = compute_cas_write_latency(ctrl_num) - 9; unsigned int mpr = 0; /* serial */ unsigned int wc_lat; - const unsigned int mclk_ps = get_memory_clk_period_ps(); + const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); if (popts->rtt_override) rtt_wr = popts->rtt_wr_override_value; @@ -1002,7 +1010,8 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, } #elif defined(CONFIG_SYS_FSL_DDR3) /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ -static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, +static void set_ddr_sdram_mode_2(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts, const common_timing_params_t *common_dimm, const unsigned int unq_mrs_en) @@ -1013,7 +1022,7 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */ unsigned int srt = 0; /* self-refresh temerature, normal range */ unsigned int asr = 0; /* auto self-refresh disable */ - unsigned int cwl = compute_cas_write_latency() - 5; + unsigned int cwl = compute_cas_write_latency(ctrl_num) - 5; unsigned int pasr = 0; /* partial array self refresh disable */ if (popts->rtt_override) @@ -1077,7 +1086,8 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, #else /* for DDR2 and DDR1 */ /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */ -static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr, +static void set_ddr_sdram_mode_2(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts, const common_timing_params_t *common_dimm, const unsigned int unq_mrs_en) @@ -1144,7 +1154,8 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr, } /* DDR SDRAM Mode configuration 10 (DDR_SDRAM_MODE_10) */ -static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr, +static void set_ddr_sdram_mode_10(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts, const common_timing_params_t *common_dimm, const unsigned int unq_mrs_en) @@ -1152,7 +1163,7 @@ static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr, int i; unsigned short esdmode6 = 0; /* Extended SDRAM mode 6 */ unsigned short esdmode7 = 0; /* Extended SDRAM mode 7 */ - unsigned int tccdl_min = picos_to_mclk(common_dimm->tccdl_ps); + unsigned int tccdl_min = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps); esdmode6 = ((tccdl_min - 4) & 0x7) << 10; @@ -1196,14 +1207,15 @@ static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr, #endif /* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */ -static void set_ddr_sdram_interval(fsl_ddr_cfg_regs_t *ddr, - const memctl_options_t *popts, - const common_timing_params_t *common_dimm) +static void set_ddr_sdram_interval(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, + const memctl_options_t *popts, + const common_timing_params_t *common_dimm) { unsigned int refint; /* Refresh interval */ unsigned int bstopre; /* Precharge interval */ - refint = picos_to_mclk(common_dimm->refresh_rate_ps); + refint = picos_to_mclk(ctrl_num, common_dimm->refresh_rate_ps); bstopre = popts->bstopre; @@ -1217,7 +1229,8 @@ static void set_ddr_sdram_interval(fsl_ddr_cfg_regs_t *ddr, #ifdef CONFIG_SYS_FSL_DDR4 /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ -static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, +static void set_ddr_sdram_mode(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts, const common_timing_params_t *common_dimm, unsigned int cas_latency, @@ -1292,7 +1305,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, * 1=fast exit DLL on (tXP) */ - wr_mclk = picos_to_mclk(common_dimm->twr_ps); + wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); if (wr_mclk <= 24) { wr = wr_table[wr_mclk - 10]; } else { @@ -1387,7 +1400,8 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, #elif defined(CONFIG_SYS_FSL_DDR3) /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ -static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, +static void set_ddr_sdram_mode(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts, const common_timing_params_t *common_dimm, unsigned int cas_latency, @@ -1466,7 +1480,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, */ dll_on = 1; - wr_mclk = picos_to_mclk(common_dimm->twr_ps); + wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps); if (wr_mclk <= 16) { wr = wr_table[wr_mclk - 5]; } else { @@ -1582,7 +1596,8 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, #else /* !CONFIG_SYS_FSL_DDR3 */ /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */ -static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, +static void set_ddr_sdram_mode(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts, const common_timing_params_t *common_dimm, unsigned int cas_latency, @@ -1654,7 +1669,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, #if defined(CONFIG_SYS_FSL_DDR1) wr = 0; /* Historical */ #elif defined(CONFIG_SYS_FSL_DDR2) - wr = picos_to_mclk(common_dimm->twr_ps); + wr = picos_to_mclk(ctrl_num, common_dimm->twr_ps); #endif dll_res = 0; mode = 0; @@ -1842,15 +1857,16 @@ static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr) debug("FSLDDR: timing_cfg_6 = 0x%08x\n", ddr->timing_cfg_6); } -static void set_timing_cfg_7(fsl_ddr_cfg_regs_t *ddr, - const common_timing_params_t *common_dimm) +static void set_timing_cfg_7(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, + const common_timing_params_t *common_dimm) { unsigned int txpr, tcksre, tcksrx; unsigned int cke_rst, cksre, cksrx, par_lat, cs_to_cmd; - txpr = max(5U, picos_to_mclk(common_dimm->trfc1_ps + 10000)); - tcksre = max(5U, picos_to_mclk(10000)); - tcksrx = max(5U, picos_to_mclk(10000)); + txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000)); + tcksre = max(5U, picos_to_mclk(ctrl_num, 10000)); + tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000)); par_lat = 0; cs_to_cmd = 0; @@ -1883,14 +1899,15 @@ static void set_timing_cfg_7(fsl_ddr_cfg_regs_t *ddr, debug("FSLDDR: timing_cfg_7 = 0x%08x\n", ddr->timing_cfg_7); } -static void set_timing_cfg_8(fsl_ddr_cfg_regs_t *ddr, +static void set_timing_cfg_8(const unsigned int ctrl_num, + fsl_ddr_cfg_regs_t *ddr, const memctl_options_t *popts, const common_timing_params_t *common_dimm, unsigned int cas_latency) { unsigned int rwt_bg, wrt_bg, rrt_bg, wwt_bg; unsigned int acttoact_bg, wrtord_bg, pre_all_rec; - unsigned int tccdl = picos_to_mclk(common_dimm->tccdl_ps); + unsigned int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps); unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) + ((ddr->timing_cfg_2 & 0x00040000) >> 14); @@ -1914,8 +1931,8 @@ static void set_timing_cfg_8(fsl_ddr_cfg_regs_t *ddr, wwt_bg = tccdl - 4; } - acttoact_bg = picos_to_mclk(common_dimm->trrdl_ps); - wrtord_bg = max(4U, picos_to_mclk(7500)); + acttoact_bg = picos_to_mclk(ctrl_num, common_dimm->trrdl_ps); + wrtord_bg = max(4U, picos_to_mclk(ctrl_num, 7500)); if (popts->otf_burst_chop_en) wrtord_bg += 2; @@ -2147,7 +2164,8 @@ check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) } unsigned int -compute_fsl_memctl_config_regs(const memctl_options_t *popts, +compute_fsl_memctl_config_regs(const unsigned int ctrl_num, + const memctl_options_t *popts, fsl_ddr_cfg_regs_t *ddr, const common_timing_params_t *common_dimm, const dimm_params_t *dimm_params, @@ -2319,14 +2337,14 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, set_ddr_eor(ddr, popts); #if !defined(CONFIG_SYS_FSL_DDR1) - set_timing_cfg_0(ddr, popts, dimm_params); + set_timing_cfg_0(ctrl_num, ddr, popts, dimm_params); #endif - set_timing_cfg_3(ddr, popts, common_dimm, cas_latency, + set_timing_cfg_3(ctrl_num, ddr, popts, common_dimm, cas_latency, additive_latency); - set_timing_cfg_1(ddr, popts, common_dimm, cas_latency); - set_timing_cfg_2(ddr, popts, common_dimm, - cas_latency, additive_latency); + set_timing_cfg_1(ctrl_num, ddr, popts, common_dimm, cas_latency); + set_timing_cfg_2(ctrl_num, ddr, popts, common_dimm, + cas_latency, additive_latency); set_ddr_cdr1(ddr, popts); set_ddr_cdr2(ddr, popts); @@ -2338,15 +2356,15 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, if ((ip_rev > 0x40700) && (popts->cswl_override != 0)) ddr->debug[18] = popts->cswl_override; - set_ddr_sdram_cfg_2(ddr, popts, unq_mrs_en); - set_ddr_sdram_mode(ddr, popts, common_dimm, - cas_latency, additive_latency, unq_mrs_en); - set_ddr_sdram_mode_2(ddr, popts, common_dimm, unq_mrs_en); + set_ddr_sdram_cfg_2(ctrl_num, ddr, popts, unq_mrs_en); + set_ddr_sdram_mode(ctrl_num, ddr, popts, common_dimm, + cas_latency, additive_latency, unq_mrs_en); + set_ddr_sdram_mode_2(ctrl_num, ddr, popts, common_dimm, unq_mrs_en); #ifdef CONFIG_SYS_FSL_DDR4 set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en); - set_ddr_sdram_mode_10(ddr, popts, common_dimm, unq_mrs_en); + set_ddr_sdram_mode_10(ctrl_num, ddr, popts, common_dimm, unq_mrs_en); #endif - set_ddr_sdram_interval(ddr, popts, common_dimm); + set_ddr_sdram_interval(ctrl_num, ddr, popts, common_dimm); set_ddr_data_init(ddr); set_ddr_sdram_clk_cntl(ddr, popts); set_ddr_init_addr(ddr); @@ -2356,8 +2374,8 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, #ifdef CONFIG_SYS_FSL_DDR4 set_ddr_sdram_cfg_3(ddr, popts); set_timing_cfg_6(ddr); - set_timing_cfg_7(ddr, common_dimm); - set_timing_cfg_8(ddr, popts, common_dimm, cas_latency); + set_timing_cfg_7(ctrl_num, ddr, common_dimm); + set_timing_cfg_8(ctrl_num, ddr, popts, common_dimm, cas_latency); set_timing_cfg_9(ddr); set_ddr_dq_mapping(ddr, dimm_params); #endif diff --git a/drivers/ddr/fsl/ddr1_dimm_params.c b/drivers/ddr/fsl/ddr1_dimm_params.c index 7df27b90b76..7f1c3afcc47 100644 --- a/drivers/ddr/fsl/ddr1_dimm_params.c +++ b/drivers/ddr/fsl/ddr1_dimm_params.c @@ -228,10 +228,10 @@ compute_derated_DDR1_CAS_latency(unsigned int mclk_ps) * * FIXME: use #define for the retvals */ -unsigned int -ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd, - dimm_params_t *pdimm, - unsigned int dimm_number) +unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, + const ddr1_spd_eeprom_t *spd, + dimm_params_t *pdimm, + unsigned int dimm_number) { unsigned int retval; @@ -311,16 +311,16 @@ ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd, & ~(1 << pdimm->caslat_x_minus_1)); /* Compute CAS latencies below that defined by SPD */ - pdimm->caslat_lowest_derated - = compute_derated_DDR1_CAS_latency(get_memory_clk_period_ps()); + pdimm->caslat_lowest_derated = compute_derated_DDR1_CAS_latency( + get_memory_clk_period_ps(ctrl_num)); /* Compute timing parameters */ pdimm->trcd_ps = spd->trcd * 250; pdimm->trp_ps = spd->trp * 250; pdimm->tras_ps = spd->tras * 1000; - pdimm->twr_ps = mclk_to_picos(3); - pdimm->twtr_ps = mclk_to_picos(1); + pdimm->twr_ps = mclk_to_picos(ctrl_num, 3); + pdimm->twtr_ps = mclk_to_picos(ctrl_num, 1); pdimm->trfc_ps = compute_trfc_ps_from_spd(0, spd->trfc); pdimm->trrd_ps = spd->trrd * 250; @@ -335,7 +335,7 @@ ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd, pdimm->tdh_ps = convert_bcd_hundredths_to_cycle_time_ps(spd->data_hold); - pdimm->trtp_ps = mclk_to_picos(2); /* By the book. */ + pdimm->trtp_ps = mclk_to_picos(ctrl_num, 2); /* By the book. */ pdimm->tdqsq_max_ps = spd->tdqsq * 10; pdimm->tqhs_ps = spd->tqhs * 10; diff --git a/drivers/ddr/fsl/ddr2_dimm_params.c b/drivers/ddr/fsl/ddr2_dimm_params.c index d865df78a8d..49cc1a07ffd 100644 --- a/drivers/ddr/fsl/ddr2_dimm_params.c +++ b/drivers/ddr/fsl/ddr2_dimm_params.c @@ -211,10 +211,10 @@ compute_derated_DDR2_CAS_latency(unsigned int mclk_ps) * * FIXME: use #define for the retvals */ -unsigned int -ddr_compute_dimm_parameters(const ddr2_spd_eeprom_t *spd, - dimm_params_t *pdimm, - unsigned int dimm_number) +unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, + const ddr2_spd_eeprom_t *spd, + dimm_params_t *pdimm, + unsigned int dimm_number) { unsigned int retval; @@ -310,8 +310,8 @@ ddr_compute_dimm_parameters(const ddr2_spd_eeprom_t *spd, & ~(1 << pdimm->caslat_x_minus_1)); /* Compute CAS latencies below that defined by SPD */ - pdimm->caslat_lowest_derated - = compute_derated_DDR2_CAS_latency(get_memory_clk_period_ps()); + pdimm->caslat_lowest_derated = compute_derated_DDR2_CAS_latency( + get_memory_clk_period_ps(ctrl_num)); /* Compute timing parameters */ pdimm->trcd_ps = spd->trcd * 250; diff --git a/drivers/ddr/fsl/ddr3_dimm_params.c b/drivers/ddr/fsl/ddr3_dimm_params.c index a4b8c101f53..69177150ec5 100644 --- a/drivers/ddr/fsl/ddr3_dimm_params.c +++ b/drivers/ddr/fsl/ddr3_dimm_params.c @@ -83,10 +83,10 @@ compute_ranksize(const ddr3_spd_eeprom_t *spd) * Writes the results to the dimm_params_t structure pointed by pdimm. * */ -unsigned int -ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, - dimm_params_t *pdimm, - unsigned int dimm_number) +unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, + const ddr3_spd_eeprom_t *spd, + dimm_params_t *pdimm, + unsigned int dimm_number) { unsigned int retval; unsigned int mtb_ps; diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index aaddc8fa087..bbfb4ee4179 100644 --- a/drivers/ddr/fsl/ddr4_dimm_params.c +++ b/drivers/ddr/fsl/ddr4_dimm_params.c @@ -119,10 +119,10 @@ compute_ranksize(const struct ddr4_spd_eeprom_s *spd) * Writes the results to the dimm_params_t structure pointed by pdimm. * */ -unsigned int -ddr_compute_dimm_parameters(const generic_spd_eeprom_t *spd, - dimm_params_t *pdimm, - unsigned int dimm_number) +unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, + const generic_spd_eeprom_t *spd, + dimm_params_t *pdimm, + unsigned int dimm_number) { unsigned int retval; int i; diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index 9cca4a06dd5..d9fce7d2f34 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -287,7 +287,7 @@ step2: bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK) >> SDRAM_CFG_DBW_SHIFT); timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 / - (get_ddr_freq(0) >> 20)) << 2; + (get_ddr_freq(ctrl_num) >> 20)) << 2; total_gb_size_per_controller >>= 4; /* shift down to gb size */ debug("total %d GB\n", total_gb_size_per_controller); debug("Need to wait up to %d * 10ms\n", timeout); diff --git a/drivers/ddr/fsl/lc_common_dimm_params.c b/drivers/ddr/fsl/lc_common_dimm_params.c index 73db4446153..b295344c4de 100644 --- a/drivers/ddr/fsl/lc_common_dimm_params.c +++ b/drivers/ddr/fsl/lc_common_dimm_params.c @@ -13,7 +13,8 @@ #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4) static unsigned int -compute_cas_latency(const dimm_params_t *dimm_params, +compute_cas_latency(const unsigned int ctrl_num, + const dimm_params_t *dimm_params, common_timing_params_t *outpdimm, unsigned int number_of_dimms) { @@ -22,7 +23,7 @@ compute_cas_latency(const dimm_params_t *dimm_params, unsigned int caslat_actual; unsigned int retry = 16; unsigned int tmp; - const unsigned int mclk_ps = get_memory_clk_period_ps(); + const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); #ifdef CONFIG_SYS_FSL_DDR3 const unsigned int taamax = 20000; #else @@ -72,12 +73,13 @@ compute_cas_latency(const dimm_params_t *dimm_params, } #else /* for DDR1 and DDR2 */ static unsigned int -compute_cas_latency(const dimm_params_t *dimm_params, +compute_cas_latency(const unsigned int ctrl_num, + const dimm_params_t *dimm_params, common_timing_params_t *outpdimm, unsigned int number_of_dimms) { int i; - const unsigned int mclk_ps = get_memory_clk_period_ps(); + const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num); unsigned int lowest_good_caslat; unsigned int not_ok; unsigned int temp1, temp2; @@ -212,7 +214,8 @@ compute_cas_latency(const dimm_params_t *dimm_params, * by dimm_params. */ unsigned int -compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, +compute_lowest_common_dimm_parameters(const unsigned int ctrl_num, + const dimm_params_t *dimm_params, common_timing_params_t *outpdimm, const unsigned int number_of_dimms) { @@ -442,7 +445,8 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, printf("ERROR: Mix different RDIMM detected!\n"); /* calculate cas latency for all DDR types */ - if (compute_cas_latency(dimm_params, outpdimm, number_of_dimms)) + if (compute_cas_latency(ctrl_num, dimm_params, + outpdimm, number_of_dimms)) return 1; /* Determine if all DIMMs ECC capable. */ @@ -518,11 +522,12 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, #if defined(CONFIG_SYS_FSL_DDR2) if ((outpdimm->lowest_common_spd_caslat < 4) && - (picos_to_mclk(trcd_ps) > outpdimm->lowest_common_spd_caslat)) { - additive_latency = picos_to_mclk(trcd_ps) - + (picos_to_mclk(ctrl_num, trcd_ps) > + outpdimm->lowest_common_spd_caslat)) { + additive_latency = picos_to_mclk(ctrl_num, trcd_ps) - outpdimm->lowest_common_spd_caslat; - if (mclk_to_picos(additive_latency) > trcd_ps) { - additive_latency = picos_to_mclk(trcd_ps); + if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) { + additive_latency = picos_to_mclk(ctrl_num, trcd_ps); debug("setting additive_latency to %u because it was " " greater than tRCD_ps\n", additive_latency); } @@ -534,7 +539,7 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, * * AL <= tRCD(min) */ - if (mclk_to_picos(additive_latency) > trcd_ps) { + if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) { printf("Error: invalid additive latency exceeds tRCD(min).\n"); return 1; } diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index 6f291ebc032..f49939b1359 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -450,7 +450,8 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, &(pinfo->spd_installed_dimms[i][j]); dimm_params_t *pdimm = &(pinfo->dimm_params[i][j]); - retval = compute_dimm_parameters(spd, pdimm, i); + retval = compute_dimm_parameters( + i, spd, pdimm, j); #ifdef CONFIG_SYS_DDR_RAW_TIMING if (!i && !j && retval) { printf("SPD error on controller %d! " @@ -507,10 +508,11 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, for (i = first_ctrl; i <= last_ctrl; i++) { debug("Computing lowest common DIMM" " parameters for memctl=%u\n", i); - compute_lowest_common_dimm_parameters( - pinfo->dimm_params[i], - &timing_params[i], - CONFIG_DIMM_SLOTS_PER_CTLR); + compute_lowest_common_dimm_parameters + (i, + pinfo->dimm_params[i], + &timing_params[i], + CONFIG_DIMM_SLOTS_PER_CTLR); } case STEP_GATHER_OPTS: @@ -562,12 +564,13 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, continue; } - compute_fsl_memctl_config_regs( - &pinfo->memctl_opts[i], - &ddr_reg[i], &timing_params[i], - pinfo->dimm_params[i], - dbw_capacity_adjust[i], - size_only); + compute_fsl_memctl_config_regs + (i, + &pinfo->memctl_opts[i], + &ddr_reg[i], &timing_params[i], + pinfo->dimm_params[i], + dbw_capacity_adjust[i], + size_only); } default: diff --git a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c index 8f4d01ad856..6752d4d29e0 100644 --- a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c +++ b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c @@ -426,7 +426,7 @@ step2: bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK) >> SDRAM_CFG_DBW_SHIFT); timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 / - (get_ddr_freq(0) >> 20)) << 1; + (get_ddr_freq(ctrl_num) >> 20)) << 1; #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 timeout_save = timeout; #endif @@ -538,12 +538,14 @@ step2: case 1: out_be32(&ddr->cs1_bnds, regs->cs[csn].bnds); break; +#if CONFIG_CHIP_SELECTS_PER_CTRL > 2 case 2: out_be32(&ddr->cs2_bnds, regs->cs[csn].bnds); break; case 3: out_be32(&ddr->cs3_bnds, regs->cs[csn].bnds); break; +#endif } clrbits_be32(&ddr->sdram_cfg, 0x2); } diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c index 6d098d1fa2f..5beb11b02b4 100644 --- a/drivers/ddr/fsl/options.c +++ b/drivers/ddr/fsl/options.c @@ -732,7 +732,7 @@ unsigned int populate_memctl_options(int all_dimms_registered, #endif /* Global Timing Parameters. */ - debug("mclk_ps = %u ps\n", get_memory_clk_period_ps()); + debug("mclk_ps = %u ps\n", get_memory_clk_period_ps(ctrl_num)); /* Pick a caslat override. */ popts->cas_latency_override = 0; @@ -785,7 +785,7 @@ unsigned int populate_memctl_options(int all_dimms_registered, * FIXME: width, was considering looking at pdimm->primary_sdram_width */ #if defined(CONFIG_SYS_FSL_DDR1) - popts->tfaw_window_four_activates_ps = mclk_to_picos(1); + popts->tfaw_window_four_activates_ps = mclk_to_picos(ctrl_num, 1); #elif defined(CONFIG_SYS_FSL_DDR2) /* @@ -1036,7 +1036,7 @@ done: if (pdimm[0].n_ranks == 4) popts->quad_rank_present = 1; - ddr_freq = get_ddr_freq(0) / 1000000; + ddr_freq = get_ddr_freq(ctrl_num) / 1000000; if (popts->registered_dimm_en) { popts->rcw_override = 1; popts->rcw_1 = 0x000a5a00; diff --git a/drivers/ddr/fsl/util.c b/drivers/ddr/fsl/util.c index 58b519b4036..ad569de27a4 100644 --- a/drivers/ddr/fsl/util.c +++ b/drivers/ddr/fsl/util.c @@ -43,9 +43,9 @@ u32 fsl_ddr_get_version(void) * propagation, compute a suitably rounded mclk_ps to compute * a working memory controller configuration. */ -unsigned int get_memory_clk_period_ps(void) +unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num) { - unsigned int data_rate = get_ddr_freq(0); + unsigned int data_rate = get_ddr_freq(ctrl_num); unsigned int result; /* Round to nearest 10ps, being careful about 64-bit multiply/divide */ @@ -59,10 +59,10 @@ unsigned int get_memory_clk_period_ps(void) } /* Convert picoseconds into DRAM clock cycles (rounding up if needed). */ -unsigned int picos_to_mclk(unsigned int picos) +unsigned int picos_to_mclk(const unsigned int ctrl_num, unsigned int picos) { unsigned long long clks, clks_rem; - unsigned long data_rate = get_ddr_freq(0); + unsigned long data_rate = get_ddr_freq(ctrl_num); /* Short circuit for zero picos */ if (!picos) @@ -88,9 +88,9 @@ unsigned int picos_to_mclk(unsigned int picos) return (unsigned int) clks; } -unsigned int mclk_to_picos(unsigned int mclk) +unsigned int mclk_to_picos(const unsigned int ctrl_num, unsigned int mclk) { - return get_memory_clk_period_ps() * mclk; + return get_memory_clk_period_ps(ctrl_num) * mclk; } #ifdef CONFIG_PPC diff --git a/include/fsl_ddr.h b/include/fsl_ddr.h index 3286c95907c..96fde91687d 100644 --- a/include/fsl_ddr.h +++ b/include/fsl_ddr.h @@ -44,11 +44,12 @@ u32 fsl_ddr_get_version(void); * to this specific DDR technology. */ static __inline__ int -compute_dimm_parameters(const generic_spd_eeprom_t *spd, +compute_dimm_parameters(const unsigned int ctrl_num, + const generic_spd_eeprom_t *spd, dimm_params_t *pdimm, unsigned int dimm_number) { - return ddr_compute_dimm_parameters(spd, pdimm, dimm_number); + return ddr_compute_dimm_parameters(ctrl_num, spd, pdimm, dimm_number); } #endif @@ -92,13 +93,15 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, unsigned int size_only); const char *step_to_string(unsigned int step); -unsigned int compute_fsl_memctl_config_regs(const memctl_options_t *popts, +unsigned int compute_fsl_memctl_config_regs(const unsigned int ctrl_num, + const memctl_options_t *popts, fsl_ddr_cfg_regs_t *ddr, const common_timing_params_t *common_dimm, const dimm_params_t *dimm_parameters, unsigned int dbw_capacity_adjust, unsigned int size_only); unsigned int compute_lowest_common_dimm_parameters( + const unsigned int ctrl_num, const dimm_params_t *dimm_params, common_timing_params_t *outpdimm, unsigned int number_of_dimms); @@ -108,9 +111,9 @@ unsigned int populate_memctl_options(int all_dimms_registered, unsigned int ctrl_num); void check_interleaving_options(fsl_ddr_info_t *pinfo); -unsigned int mclk_to_picos(unsigned int mclk); -unsigned int get_memory_clk_period_ps(void); -unsigned int picos_to_mclk(unsigned int picos); +unsigned int mclk_to_picos(const unsigned int ctrl_num, unsigned int mclk); +unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num); +unsigned int picos_to_mclk(const unsigned int ctrl_num, unsigned int picos); void fsl_ddr_set_lawbar( const common_timing_params_t *memctl_common_params, unsigned int memctl_interleaved, diff --git a/include/fsl_ddr_dimm_params.h b/include/fsl_ddr_dimm_params.h index 09a67a68029..751e9351174 100644 --- a/include/fsl_ddr_dimm_params.h +++ b/include/fsl_ddr_dimm_params.h @@ -112,7 +112,7 @@ typedef struct dimm_params_s { #endif } dimm_params_t; -extern unsigned int ddr_compute_dimm_parameters( +unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, const generic_spd_eeprom_t *spd, dimm_params_t *pdimm, unsigned int dimm_number); -- cgit v1.3.1 From 27f277fe33eb824308a4547d2e96bf511fb91d6b Mon Sep 17 00:00:00 2001 From: Kuldip Giroh Date: Tue, 6 Jan 2015 13:18:53 -0800 Subject: ARMv8/LS2085A: HugeTLB support is required by default in LS NADK LS NADK memory manager by default works on HugeTLB. Hence bootargs must include parameters default_hugepagesz (default hugepagesize, hugepagesz (hugepage size) and hugepages (number of hugepages to be reserved in kernel for the given size). Signed-off-by: Kuldip Giroh Reviewed-by: York Sun --- include/configs/ls2085a_common.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 38984432b5a..55e7307cbc2 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -274,7 +274,9 @@ "console=ttyAMA0,38400n8\0" #define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \ - "earlyprintk=uart8250-8bit,0x21c0600" + "earlyprintk=uart8250-8bit,0x21c0600 " \ + "default_hugepagesz=2m hugepagesz=2m " \ + "hugepages=16" #define CONFIG_BOOTCOMMAND "cp.b $kernel_start $kernel_load " \ "$kernel_size && bootm $kernel_load" #define CONFIG_BOOTDELAY 1 -- cgit v1.3.1 From 064d031ca6490d9641bbe308690b1f15b1f56077 Mon Sep 17 00:00:00 2001 From: York Sun Date: Tue, 6 Jan 2015 13:18:54 -0800 Subject: ARMv8/LS2085A: Adjust system clock and DDR clock Set system clock to 100MHz and DDR clock to 133MHz. Signed-off-by: York Sun --- include/configs/ls2085a_common.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 55e7307cbc2..387f9047058 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -249,7 +249,8 @@ /* Physical Memory Map */ /* fixme: these need to be checked against the board */ #define CONFIG_CHIP_SELECTS_PER_CTRL 4 -#define CONFIG_SYS_CLK_FREQ 133333333 +#define CONFIG_SYS_CLK_FREQ 100000000 +#define CONFIG_DDR_CLK_FREQ 133333333 #define CONFIG_NR_DRAM_BANKS 3 -- cgit v1.3.1 From e32d59a2fa6446b64167bba31c0dd40eb023e8bb Mon Sep 17 00:00:00 2001 From: York Sun Date: Tue, 6 Jan 2015 13:18:55 -0800 Subject: driver/ddr/fsl: Add sync of refresh Add sync of refresh for multiple DDR controllers. DDRC initialization needs to complete first. Code is re-ordered to keep refresh close. Signed-off-by: York Sun --- README | 3 +++ drivers/ddr/fsl/main.c | 4 ++++ drivers/ddr/fsl/util.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/fsl_ddr.h | 2 ++ 4 files changed, 64 insertions(+) (limited to 'include') diff --git a/README b/README index ba57dc5617a..6800b959ca5 100644 --- a/README +++ b/README @@ -4916,6 +4916,9 @@ Low Level (hardware related) configuration options: - CONFIG_FSL_DDR_INTERACTIVE Enable interactive DDR debugging. See doc/README.fsl-ddr. +- CONFIG_FSL_DDR_SYNC_REFRESH + Enable sync of refresh for multiple controllers. + - CONFIG_SYS_83XX_DDR_USES_CS0 Only for 83xx systems. If specified, then DDR should be configured using CS0 and CS1 instead of CS2 and CS3. diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index f49939b1359..b72b24290ec 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -692,6 +692,10 @@ phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo) } } +#ifdef CONFIG_FSL_DDR_SYNC_REFRESH + fsl_ddr_sync_memctl_refresh(first_ctrl, last_ctrl); +#endif + #ifdef CONFIG_PPC /* program LAWs */ for (i = first_ctrl; i <= last_ctrl; i++) { diff --git a/drivers/ddr/fsl/util.c b/drivers/ddr/fsl/util.c index ad569de27a4..664081b1b83 100644 --- a/drivers/ddr/fsl/util.c +++ b/drivers/ddr/fsl/util.c @@ -308,3 +308,58 @@ void board_add_ram_info(int use_default) { detail_board_ddr_info(); } + +#ifdef CONFIG_FSL_DDR_SYNC_REFRESH +#define DDRC_DEBUG20_INIT_DONE 0x80000000 +#define DDRC_DEBUG2_RF 0x00000040 +void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl, + unsigned int last_ctrl) +{ + unsigned int i; + u32 ddrc_debug20; + u32 ddrc_debug2[CONFIG_NUM_DDR_CONTROLLERS] = {}; + u32 *ddrc_debug2_p[CONFIG_NUM_DDR_CONTROLLERS] = {}; + struct ccsr_ddr __iomem *ddr; + + for (i = first_ctrl; i <= last_ctrl; i++) { + switch (i) { + case 0: + ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; + break; +#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) + case 1: + ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; + break; +#endif +#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) + case 2: + ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; + break; +#endif +#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) + case 3: + ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; + break; +#endif + default: + printf("%s unexpected ctrl = %u\n", __func__, i); + return; + } + ddrc_debug20 = ddr_in32(&ddr->debug[19]); + ddrc_debug2_p[i] = &ddr->debug[1]; + while (!(ddrc_debug20 & DDRC_DEBUG20_INIT_DONE)) { + /* keep polling until DDRC init is done */ + udelay(100); + ddrc_debug20 = ddr_in32(&ddr->debug[19]); + } + ddrc_debug2[i] = ddr_in32(&ddr->debug[1]) | DDRC_DEBUG2_RF; + } + /* + * Sync refresh + * This is put together to make sure the refresh reqeusts are sent + * closely to each other. + */ + for (i = first_ctrl; i <= last_ctrl; i++) + ddr_out32(ddrc_debug2_p[i], ddrc_debug2[i]); +} +#endif /* CONFIG_FSL_DDR_SYNC_REFRESH */ diff --git a/include/fsl_ddr.h b/include/fsl_ddr.h index 96fde91687d..feccef9c9cd 100644 --- a/include/fsl_ddr.h +++ b/include/fsl_ddr.h @@ -118,6 +118,8 @@ void fsl_ddr_set_lawbar( const common_timing_params_t *memctl_common_params, unsigned int memctl_interleaved, unsigned int ctrl_num); +void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl, + unsigned int last_ctrl); int fsl_ddr_interactive_env_var_exists(void); unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set); -- cgit v1.3.1 From 40e61f8e54f8262a6e85c127c5d9dc240253382a Mon Sep 17 00:00:00 2001 From: Arnab Basu Date: Tue, 6 Jan 2015 13:18:56 -0800 Subject: ARMv8/ls2085a: Switch to passing earlycon to kernel Since Linux v3.16-rc1 earlyprintk has been removed for arm64. Switch to using earlycon. Signed-off-by: Arnab Basu Signed-off-by: York Sun --- include/configs/ls2085a_common.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 387f9047058..7e8d944dff7 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -274,10 +274,10 @@ "kernel_size=0x1000000\0" \ "console=ttyAMA0,38400n8\0" -#define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \ - "earlyprintk=uart8250-8bit,0x21c0600 " \ - "default_hugepagesz=2m hugepagesz=2m " \ - "hugepages=16" +#define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \ + "earlycon=uart8250,mmio,0x21c0600,115200 " \ + "default_hugepagesz=2m hugepagesz=2m " \ + "hugepages=16" #define CONFIG_BOOTCOMMAND "cp.b $kernel_start $kernel_load " \ "$kernel_size && bootm $kernel_load" #define CONFIG_BOOTDELAY 1 -- cgit v1.3.1 From 052ddd5c812ad9f30e7cf9023e50fde882bd65da Mon Sep 17 00:00:00 2001 From: Stuart Yoder Date: Tue, 6 Jan 2015 13:18:57 -0800 Subject: ARMv8/ls2085a: Move kernel image load address Move the load address of the kernel image to get it away from the region of the uncompressed kernel. Signed-off-by: Stuart Yoder Reviewed-by: York Sun --- include/configs/ls2085a_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 7e8d944dff7..befd4c72577 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -270,7 +270,7 @@ "fdt_high=0xffffffffffffffff\0" \ "initrd_high=0xffffffffffffffff\0" \ "kernel_start=0x581200000\0" \ - "kernel_load=0x806f0000\0" \ + "kernel_load=0xa0000000\0" \ "kernel_size=0x1000000\0" \ "console=ttyAMA0,38400n8\0" -- cgit v1.3.1 From bbeeb8bec084d9fff2cd16d2577ca285f8e66b72 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Tue, 6 Jan 2015 13:18:58 -0800 Subject: ls2085/configs: Ensure right banners are printed for EMU and SIMU This patch enusres that right banners are printed for LS2085A emulator and simulator platforms. Signed-off-by: Bhupesh Sharma Reviewed-by: York Sun --- include/configs/ls2085a_common.h | 3 --- include/configs/ls2085a_emu.h | 3 +++ include/configs/ls2085a_simu.h | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index befd4c72577..55f4c963608 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -27,9 +27,6 @@ #define CONFIG_SKIP_LOWLEVEL_INIT #define CONFIG_BOARD_EARLY_INIT_F 1 -#define CONFIG_IDENT_STRING " LS2085A-EMU" -#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-EMU" - /* Flat Device Tree Definitions */ #define CONFIG_OF_LIBFDT #define CONFIG_OF_BOARD_SETUP diff --git a/include/configs/ls2085a_emu.h b/include/configs/ls2085a_emu.h index 487cd99c5dc..2d2e1ea0bdc 100644 --- a/include/configs/ls2085a_emu.h +++ b/include/configs/ls2085a_emu.h @@ -9,6 +9,9 @@ #include "ls2085a_common.h" +#define CONFIG_IDENT_STRING " LS2085A-EMU" +#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-EMU" + #define CONFIG_DDR_SPD #define CONFIG_SYS_FSL_DDR_EMU /* Support emulator */ #define SPD_EEPROM_ADDRESS1 0x51 diff --git a/include/configs/ls2085a_simu.h b/include/configs/ls2085a_simu.h index 0f40b787b47..af34f3f95d6 100644 --- a/include/configs/ls2085a_simu.h +++ b/include/configs/ls2085a_simu.h @@ -9,6 +9,9 @@ #include "ls2085a_common.h" +#define CONFIG_IDENT_STRING " LS2085A-SIMU" +#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-SIMU" + /* SMSC 91C111 ethernet configuration */ #define CONFIG_SMC91111 #define CONFIG_SMC91111_BASE (0x2210000) -- cgit v1.3.1 From 4f2532c4a4a34f0241ef9bc921044772f19f928d Mon Sep 17 00:00:00 2001 From: York Sun Date: Tue, 6 Jan 2015 13:19:01 -0800 Subject: armv8/ls2085a_emu: Enable sync of refresh Enable sync of DDR refresh for LS2085a platform. GPP DDR controllers stay in sync. DP-DDR has only one controller so it does no harm. Signed-off-by: York Sun --- include/configs/ls2085a_emu.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/configs/ls2085a_emu.h b/include/configs/ls2085a_emu.h index 2d2e1ea0bdc..a02d69450b7 100644 --- a/include/configs/ls2085a_emu.h +++ b/include/configs/ls2085a_emu.h @@ -20,4 +20,5 @@ #define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1 #define CONFIG_SYS_SPD_BUS_NUM 1 /* SPD on I2C bus 1 */ +#define CONFIG_FSL_DDR_SYNC_REFRESH #endif /* __LS2_EMU_H */ -- cgit v1.3.1 From 7b3bd9a7988a8b4c8ba22a52b4927e8e59819b12 Mon Sep 17 00:00:00 2001 From: "J. German Rivera" Date: Tue, 6 Jan 2015 13:19:02 -0800 Subject: drivers/mc: Migrated MC Flibs to 0.5.2 Upgrade Manage Complex (MC) flib API to 0.5.2. Rename directory fsl_mc to fsl-mc. Change the fsl-mc node in Linux device tree from "fsl,dprcr" to "fsl-mc". Print MC version info when appropriate. Signed-off-by: J. German Rivera Signed-off-by: Lijun Pan Reviewed-by: York Sun --- arch/arm/cpu/armv8/fsl-lsch3/cpu.c | 2 +- board/freescale/ls2085a/ls2085a.c | 18 ++- drivers/net/Makefile | 2 +- drivers/net/fsl-mc/Makefile | 10 ++ drivers/net/fsl-mc/dpmng.c | 91 +++++++++++ drivers/net/fsl-mc/fsl_dpmng_cmd.h | 49 ++++++ drivers/net/fsl-mc/mc.c | 310 +++++++++++++++++++++++++++++++++++++ drivers/net/fsl-mc/mc_sys.c | 63 ++++++++ drivers/net/fsl_mc/Makefile | 8 - drivers/net/fsl_mc/mc.c | 266 ------------------------------- include/configs/ls2085a_common.h | 4 +- include/fsl-mc/fsl_dpmng.h | 121 +++++++++++++++ include/fsl-mc/fsl_mc.h | 59 +++++++ include/fsl-mc/fsl_mc_cmd.h | 132 ++++++++++++++++ include/fsl-mc/fsl_mc_sys.h | 26 ++++ include/fsl_mc.h | 59 ------- 16 files changed, 880 insertions(+), 340 deletions(-) create mode 100644 drivers/net/fsl-mc/Makefile create mode 100644 drivers/net/fsl-mc/dpmng.c create mode 100644 drivers/net/fsl-mc/fsl_dpmng_cmd.h create mode 100644 drivers/net/fsl-mc/mc.c create mode 100644 drivers/net/fsl-mc/mc_sys.c delete mode 100644 drivers/net/fsl_mc/Makefile delete mode 100644 drivers/net/fsl_mc/mc.c create mode 100644 include/fsl-mc/fsl_dpmng.h create mode 100644 include/fsl-mc/fsl_mc.h create mode 100644 include/fsl-mc/fsl_mc_cmd.h create mode 100644 include/fsl-mc/fsl_mc_sys.h delete mode 100644 include/fsl_mc.h (limited to 'include') diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c index 42cee655462..49974878b9c 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c @@ -10,10 +10,10 @@ #include #include #include +#include #include "cpu.h" #include "mp.h" #include "speed.h" -#include DECLARE_GLOBAL_DATA_PTR; diff --git a/board/freescale/ls2085a/ls2085a.c b/board/freescale/ls2085a/ls2085a.c index ee75d1b7eda..519d61cb1e8 100644 --- a/board/freescale/ls2085a/ls2085a.c +++ b/board/freescale/ls2085a/ls2085a.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -98,7 +98,21 @@ void fdt_fixup_board_enet(void *fdt) { int offset; - offset = fdt_path_offset(fdt, "/fsl,dprc@0"); + offset = fdt_path_offset(fdt, "/fsl-mc"); + + /* + * TODO: Remove this when backward compatibility + * with old DT node (fsl,dprc@0) is no longer needed. + */ + if (offset < 0) + offset = fdt_path_offset(fdt, "/fsl,dprc@0"); + + if (offset < 0) { + printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n", + __func__, offset); + return; + } + if (get_mc_boot_status() == 0) fdt_status_okay(fdt, offset); else diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 46c4ac697d6..6e1ccdbb3d2 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -65,5 +65,5 @@ obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o obj-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \ xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o obj-$(CONFIG_ZYNQ_GEM) += zynq_gem.o -obj-$(CONFIG_FSL_MC_ENET) += fsl_mc/ +obj-$(CONFIG_FSL_MC_ENET) += fsl-mc/ obj-$(CONFIG_VSC9953) += vsc9953.o diff --git a/drivers/net/fsl-mc/Makefile b/drivers/net/fsl-mc/Makefile new file mode 100644 index 00000000000..206ac6be07a --- /dev/null +++ b/drivers/net/fsl-mc/Makefile @@ -0,0 +1,10 @@ +# +# Copyright 2014 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +# Layerscape MC driver +obj-y += mc.o \ + mc_sys.o \ + dpmng.o diff --git a/drivers/net/fsl-mc/dpmng.c b/drivers/net/fsl-mc/dpmng.c new file mode 100644 index 00000000000..cc14c7b7559 --- /dev/null +++ b/drivers/net/fsl-mc/dpmng.c @@ -0,0 +1,91 @@ +/* Copyright 2014 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include "fsl_dpmng_cmd.h" + +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info) +{ + struct mc_command cmd = { 0 }; + int err; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION, + MC_CMD_PRI_LOW, 0); + + /* send command to mc*/ + err = mc_send_command(mc_io, &cmd); + if (err) + return err; + + /* retrieve response parameters */ + DPMNG_RSP_GET_VERSION(cmd, mc_ver_info); + + return 0; +} + +int dpmng_reset_aiop(struct fsl_mc_io *mc_io, int container_id, + int aiop_tile_id) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_AIOP, + MC_CMD_PRI_LOW, 0); + DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmng_load_aiop(struct fsl_mc_io *mc_io, + int container_id, + int aiop_tile_id, + uint64_t img_iova, + uint32_t img_size) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_LOAD_AIOP, + MC_CMD_PRI_LOW, + 0); + DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size, + img_iova); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmng_run_aiop(struct fsl_mc_io *mc_io, + int container_id, + int aiop_tile_id, + const struct dpmng_aiop_run_cfg *cfg) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RUN_AIOP, + MC_CMD_PRI_LOW, + 0); + DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} + +int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io) +{ + struct mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_MC_PORTAL, + MC_CMD_PRI_LOW, + 0); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} diff --git a/drivers/net/fsl-mc/fsl_dpmng_cmd.h b/drivers/net/fsl-mc/fsl_dpmng_cmd.h new file mode 100644 index 00000000000..c9fe021f455 --- /dev/null +++ b/drivers/net/fsl-mc/fsl_dpmng_cmd.h @@ -0,0 +1,49 @@ +/* Copyright 2014 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __FSL_DPMNG_CMD_H +#define __FSL_DPMNG_CMD_H + +/* Command IDs */ +#define DPMNG_CMDID_GET_VERSION 0x831 +#define DPMNG_CMDID_RESET_AIOP 0x832 +#define DPMNG_CMDID_LOAD_AIOP 0x833 +#define DPMNG_CMDID_RUN_AIOP 0x834 +#define DPMNG_CMDID_RESET_MC_PORTAL 0x835 + +/* cmd, param, offset, width, type, arg_name */ +#define DPMNG_RSP_GET_VERSION(cmd, mc_ver_info) \ +do { \ + MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mc_ver_info->revision); \ + MC_RSP_OP(cmd, 0, 32, 32, uint32_t, mc_ver_info->major); \ + MC_RSP_OP(cmd, 1, 0, 32, uint32_t, mc_ver_info->minor); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \ + MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size, \ + img_iova) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \ + MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \ + MC_CMD_OP(cmd, 1, 0, 32, uint32_t, img_size); \ + MC_CMD_OP(cmd, 2, 0, 64, uint64_t, img_iova); \ +} while (0) + +/* cmd, param, offset, width, type, arg_name */ +#define DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg) \ +do { \ + MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \ + MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \ + MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->cores_mask); \ + MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options); \ +} while (0) + +#endif /* __FSL_DPMNG_CMD_H */ diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c new file mode 100644 index 00000000000..74b0085301c --- /dev/null +++ b/drivers/net/fsl-mc/mc.c @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; +static int mc_boot_status; + +/** + * Copying MC firmware or DPL image to DDR + */ +static int mc_copy_image(const char *title, + u64 image_addr, u32 image_size, u64 mc_ram_addr) +{ + debug("%s copied to address %p\n", title, (void *)mc_ram_addr); + memcpy((void *)mc_ram_addr, (void *)image_addr, image_size); + return 0; +} + +/** + * MC firmware FIT image parser checks if the image is in FIT + * format, verifies integrity of the image and calculates + * raw image address and size values. + * Returns 0 on success and a negative errno on error. + * task fail. + **/ +int parse_mc_firmware_fit_image(const void **raw_image_addr, + size_t *raw_image_size) +{ + int format; + void *fit_hdr; + int node_offset; + const void *data; + size_t size; + const char *uname = "firmware"; + + /* Check if the image is in NOR flash */ +#ifdef CONFIG_SYS_LS_MC_FW_IN_NOR + fit_hdr = (void *)CONFIG_SYS_LS_MC_FW_ADDR; +#else +#error "No CONFIG_SYS_LS_MC_FW_IN_xxx defined" +#endif + + /* Check if Image is in FIT format */ + format = genimg_get_format(fit_hdr); + + if (format != IMAGE_FORMAT_FIT) { + printf("fsl-mc: ERROR: Bad firmware image (not a FIT image)\n"); + return -EINVAL; + } + + if (!fit_check_format(fit_hdr)) { + printf("fsl-mc: ERROR: Bad firmware image (bad FIT header)\n"); + return -EINVAL; + } + + node_offset = fit_image_get_node(fit_hdr, uname); + + if (node_offset < 0) { + printf("fsl-mc: ERROR: Bad firmware image (missing subimage)\n"); + return -ENOENT; + } + + /* Verify MC firmware image */ + if (!(fit_image_verify(fit_hdr, node_offset))) { + printf("fsl-mc: ERROR: Bad firmware image (bad CRC)\n"); + return -EINVAL; + } + + /* Get address and size of raw image */ + fit_image_get_data(fit_hdr, node_offset, &data, &size); + + *raw_image_addr = data; + *raw_image_size = size; + + return 0; +} + +int mc_init(bd_t *bis) +{ + int error = 0; + int timeout = 200000; + struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; + u64 mc_ram_addr; + u64 mc_dpl_offset; + u32 reg_gsr; + u32 mc_fw_boot_status; + void *dpl_fdt_hdr; + int dpl_size; + const void *raw_image_addr; + size_t raw_image_size = 0; + struct fsl_mc_io mc_io; + int portal_id; + struct mc_version mc_ver_info; + + /* + * The MC private DRAM block was already carved at the end of DRAM + * by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE: + */ + if (gd->bd->bi_dram[1].start) { + mc_ram_addr = + gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size; + } else { + mc_ram_addr = + gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; + } + + /* + * Management Complex cores should be held at reset out of POR. + * U-boot should be the first software to touch MC. To be safe, + * we reset all cores again by setting GCR1 to 0. It doesn't do + * anything if they are held at reset. After we setup the firmware + * we kick off MC by deasserting the reset bit for core 0, and + * deasserting the reset bits for Command Portal Managers. + * The stop bits are not touched here. They are used to stop the + * cores when they are active. Setting stop bits doesn't stop the + * cores from fetching instructions when they are released from + * reset. + */ + out_le32(&mc_ccsr_regs->reg_gcr1, 0); + dmb(); + + error = parse_mc_firmware_fit_image(&raw_image_addr, &raw_image_size); + if (error != 0) + goto out; + /* + * Load the MC FW at the beginning of the MC private DRAM block: + */ + mc_copy_image("MC Firmware", + (u64)raw_image_addr, raw_image_size, mc_ram_addr); + + /* + * Get address and size of the DPL blob stored in flash: + */ +#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR + dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR; +#else +#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined" +#endif + + error = fdt_check_header(dpl_fdt_hdr); + if (error != 0) { + printf("fsl-mc: ERROR: Bad DPL image (bad header)\n"); + goto out; + } + + dpl_size = fdt_totalsize(dpl_fdt_hdr); + if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) { + printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n", + dpl_size); + error = -EINVAL; + goto out; + } + + /* + * Calculate offset in the MC private DRAM block at which the MC DPL + * blob is to be placed: + */ +#ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET + BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || + CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff); + + mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET; +#else + mc_dpl_offset = mc_get_dram_block_size() - + roundup(CONFIG_SYS_LS_MC_DPL_MAX_LENGTH, 4096); + + if ((mc_dpl_offset & 0x3) != 0 || mc_dpl_offset > 0xffffffff) { + printf("%s: Invalid MC DPL offset: %llu\n", + __func__, mc_dpl_offset); + error = -EINVAL; + goto out; + } +#endif + + /* + * Load the MC DPL blob at the far end of the MC private DRAM block: + * + * TODO: Should we place the DPL at a different location to match + * assumptions of MC firmware about its memory layout? + */ + mc_copy_image("MC DPL blob", + (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset); + + debug("mc_ccsr_regs %p\n", mc_ccsr_regs); + + /* + * Tell MC where the MC Firmware image was loaded in DDR: + */ + out_le32(&mc_ccsr_regs->reg_mcfbalr, (u32)mc_ram_addr); + out_le32(&mc_ccsr_regs->reg_mcfbahr, (u32)((u64)mc_ram_addr >> 32)); + out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK); + + /* + * Tell MC where the DPL blob was loaded in DDR, by indicating + * its offset relative to the beginning of the DDR block + * allocated to the MC firmware. The MC firmware is responsible + * for checking that there is no overlap between the DPL blob + * and the runtime heap and stack of the MC firmware itself. + * + * NOTE: bits [31:2] of this offset need to be stored in bits [29:0] of + * the GSR MC CCSR register. So, this offset is assumed to be 4-byte + * aligned. + * Care must be taken not to write 1s into bits 31 and 30 of the GSR in + * this case as the SoC COP or PIC will be signaled. + */ + out_le32(&mc_ccsr_regs->reg_gsr, (u32)(mc_dpl_offset >> 2)); + + printf("\nfsl-mc: Booting Management Complex ...\n"); + + /* + * Deassert reset and release MC core 0 to run + */ + out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST); + dmb(); + debug("Polling mc_ccsr_regs->reg_gsr ...\n"); + + for (;;) { + reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr); + mc_fw_boot_status = (reg_gsr & GSR_FS_MASK); + if (mc_fw_boot_status & 0x1) + break; + + udelay(1000); /* throttle polling */ + if (timeout-- <= 0) + break; + } + + if (timeout <= 0) { + printf("fsl-mc: timeout booting management complex firmware\n"); + + /* TODO: Get an error status from an MC CCSR register */ + error = -ETIMEDOUT; + goto out; + } + + if (mc_fw_boot_status != 0x1) { + /* + * TODO: Identify critical errors from the GSR register's FS + * field and for those errors, set error to -ENODEV or other + * appropriate errno, so that the status property is set to + * failure in the fsl,dprc device tree node. + */ + printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n", + reg_gsr); + } + + /* + * TODO: need to obtain the portal_id for the root container from the + * DPL + */ + portal_id = 0; + + /* + * Check that the MC firmware is responding portal commands: + */ + mc_io.mmio_regs = SOC_MC_PORTAL_ADDR(portal_id); + debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n", + portal_id, mc_io.mmio_regs); + + error = mc_get_version(&mc_io, &mc_ver_info); + if (error != 0) { + printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n", + error); + goto out; + } + + if (MC_VER_MAJOR != mc_ver_info.major) + printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n", + mc_ver_info.major, MC_VER_MAJOR); + + if (MC_VER_MINOR != mc_ver_info.minor) + printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n", + mc_ver_info.minor, MC_VER_MINOR); + + printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n", + mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision, + mc_fw_boot_status); +out: + if (error != 0) + mc_boot_status = -error; + else + mc_boot_status = 0; + + return error; +} + +int get_mc_boot_status(void) +{ + return mc_boot_status; +} + +/** + * Return the actual size of the MC private DRAM block. + * + * NOTE: For now this function always returns the minimum required size, + * However, in the future, the actual size may be obtained from an environment + * variable. + */ +unsigned long mc_get_dram_block_size(void) +{ + return CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; +} diff --git a/drivers/net/fsl-mc/mc_sys.c b/drivers/net/fsl-mc/mc_sys.c new file mode 100644 index 00000000000..7c8e003ad00 --- /dev/null +++ b/drivers/net/fsl-mc/mc_sys.c @@ -0,0 +1,63 @@ +/* + * Freescale Layerscape MC I/O wrapper + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Author: German Rivera + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#define MC_CMD_HDR_READ_CMDID(_hdr) \ + ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S)) + +/** + * mc_send_command - Send MC command and wait for response + * + * @mc_io: Pointer to MC I/O object to be used + * @cmd: MC command buffer. On input, it contains the command to send to the MC. + * On output, it contains the response from the MC if any. + * + * Depending on the sharing option specified when creating the MC portal + * wrapper, this function will use a spinlock or mutex to ensure exclusive + * access to the MC portal from the point when the command is sent until a + * response is received from the MC. + */ +int mc_send_command(struct fsl_mc_io *mc_io, + struct mc_command *cmd) +{ + enum mc_cmd_status status; + int timeout = 2000; + + mc_write_command(mc_io->mmio_regs, cmd); + + for ( ; ; ) { + status = mc_read_response(mc_io->mmio_regs, cmd); + if (status != MC_CMD_STATUS_READY) + break; + + if (--timeout == 0) { + printf("Error: Timeout waiting for MC response\n"); + return -ETIMEDOUT; + } + + udelay(500); + } + + if (status != MC_CMD_STATUS_OK) { + printf("Error: MC command failed (portal: %p, obj handle: %#x, command: %#x, status: %#x)\n", + mc_io->mmio_regs, + (unsigned int)MC_CMD_HDR_READ_AUTHID(cmd->header), + (unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header), + (unsigned int)status); + + return -EIO; + } + + return 0; +} diff --git a/drivers/net/fsl_mc/Makefile b/drivers/net/fsl_mc/Makefile deleted file mode 100644 index 483408623c4..00000000000 --- a/drivers/net/fsl_mc/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright 2014 Freescale Semiconductor, Inc. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -# Layerscape MC driver -obj-y += mc.o diff --git a/drivers/net/fsl_mc/mc.c b/drivers/net/fsl_mc/mc.c deleted file mode 100644 index df84568a945..00000000000 --- a/drivers/net/fsl_mc/mc.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 2014 Freescale Semiconductor - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; -static int mc_boot_status; - -/** - * Copying MC firmware or DPL image to DDR - */ -static int mc_copy_image(const char *title, - u64 image_addr, u32 image_size, u64 mc_ram_addr) -{ - debug("%s copied to address %p\n", title, (void *)mc_ram_addr); - memcpy((void *)mc_ram_addr, (void *)image_addr, image_size); - return 0; -} - -/** - * MC firmware FIT image parser checks if the image is in FIT - * format, verifies integrity of the image and calculates - * raw image address and size values. - * Returns 0 if success and 1 if any of the above mentioned - * task fail. - **/ - -int parse_mc_firmware_fit_image(const void **raw_image_addr, - size_t *raw_image_size) -{ - int format; - void *fit_hdr; - int node_offset; - const void *data; - size_t size; - const char *uname = "firmware"; - - /* Check if the image is in NOR flash*/ -#ifdef CONFIG_SYS_LS_MC_FW_IN_NOR - fit_hdr = (void *)CONFIG_SYS_LS_MC_FW_ADDR; -#else -#error "No CONFIG_SYS_LS_MC_FW_IN_xxx defined" -#endif - - /* Check if Image is in FIT format */ - format = genimg_get_format(fit_hdr); - - if (format != IMAGE_FORMAT_FIT) { - debug("Not a FIT image\n"); - return 1; - } - - if (!fit_check_format(fit_hdr)) { - debug("Bad FIT image format\n"); - return 1; - } - - node_offset = fit_image_get_node(fit_hdr, uname); - - if (node_offset < 0) { - debug("Can not find %s subimage\n", uname); - return 1; - } - - /* Verify MC firmware image */ - if (!(fit_image_verify(fit_hdr, node_offset))) { - debug("Bad MC firmware hash"); - return 1; - } - - /* Get address and size of raw image */ - fit_image_get_data(fit_hdr, node_offset, &data, &size); - - *raw_image_addr = data; - *raw_image_size = size; - - return 0; -} - -int mc_init(bd_t *bis) -{ - int error = 0; - int timeout = 200000; - struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR; - u64 mc_ram_addr; - u64 mc_dpl_offset; - u32 reg_gsr; - u32 mc_fw_boot_status; - void *fdt_hdr; - int dpl_size; - const void *raw_image_addr; - size_t raw_image_size = 0; - - BUILD_BUG_ON(CONFIG_SYS_LS_MC_FW_LENGTH % 4 != 0); - - /* - * The MC private DRAM block was already carved at the end of DRAM - * by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE: - */ - if (gd->bd->bi_dram[1].start) { - mc_ram_addr = - gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size; - } else { - mc_ram_addr = - gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size; - } - - /* - * Management Complex cores should be held at reset out of POR. - * U-boot should be the first software to touch MC. To be safe, - * we reset all cores again by setting GCR1 to 0. It doesn't do - * anything if they are held at reset. After we setup the firmware - * we kick off MC by deasserting the reset bit for core 0, and - * deasserting the reset bits for Command Portal Managers. - * The stop bits are not touched here. They are used to stop the - * cores when they are active. Setting stop bits doesn't stop the - * cores from fetching instructions when they are released from - * reset. - */ - out_le32(&mc_ccsr_regs->reg_gcr1, 0); - dmb(); - - error = parse_mc_firmware_fit_image(&raw_image_addr, &raw_image_size); - if (error != 0) - goto out; - /* - * Load the MC FW at the beginning of the MC private DRAM block: - */ - mc_copy_image( - "MC Firmware", - (u64)raw_image_addr, - raw_image_size, - mc_ram_addr); - - /* - * Calculate offset in the MC private DRAM block at which the MC DPL - * blob is to be placed: - */ -#ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET - BUILD_BUG_ON( - (CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 || - CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff); - - mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET; -#else - mc_dpl_offset = mc_get_dram_block_size() - - roundup(CONFIG_SYS_LS_MC_DPL_LENGTH, 4096); - - if ((mc_dpl_offset & 0x3) != 0 || mc_dpl_offset > 0xffffffff) { - printf("%s: Invalid MC DPL offset: %llu\n", - __func__, mc_dpl_offset); - error = -EINVAL; - goto out; - } -#endif - - /* Check if DPL image is in NOR flash */ -#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR - fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR; -#else -#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined" -#endif - - dpl_size = fdt_totalsize(fdt_hdr); - - /* - * Load the MC DPL blob at the far end of the MC private DRAM block: - */ - mc_copy_image( - "MC DPL blob", - (u64)fdt_hdr, - dpl_size, - mc_ram_addr + mc_dpl_offset); - - debug("mc_ccsr_regs %p\n", mc_ccsr_regs); - - /* - * Tell MC where the MC Firmware image was loaded in DDR: - */ - out_le32(&mc_ccsr_regs->reg_mcfbalr, (u32)mc_ram_addr); - out_le32(&mc_ccsr_regs->reg_mcfbahr, (u32)((u64)mc_ram_addr >> 32)); - out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK); - - /* - * Tell MC where the DPL blob was loaded in DDR, by indicating - * its offset relative to the beginning of the DDR block - * allocated to the MC firmware. The MC firmware is responsible - * for checking that there is no overlap between the DPL blob - * and the runtime heap and stack of the MC firmware itself. - * - * NOTE: bits [31:2] of this offset need to be stored in bits [29:0] of - * the GSR MC CCSR register. So, this offset is assumed to be 4-byte - * aligned. - * Care must be taken not to write 1s into bits 31 and 30 of the GSR in - * this case as the SoC COP or PIC will be signaled. - */ - out_le32(&mc_ccsr_regs->reg_gsr, (u32)(mc_dpl_offset >> 2)); - - /* - * Deassert reset and release MC core 0 to run - */ - out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST); - dmb(); - debug("Polling mc_ccsr_regs->reg_gsr ...\n"); - - for (;;) { - reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr); - mc_fw_boot_status = (reg_gsr & GSR_FS_MASK); - if (mc_fw_boot_status & 0x1) - break; - - udelay(1000); /* throttle polling */ - if (timeout-- <= 0) - break; - } - - if (timeout <= 0) { - printf("%s: timeout booting management complex firmware\n", - __func__); - - /* TODO: Get an error status from an MC CCSR register */ - error = -ETIMEDOUT; - goto out; - } - - printf("Management complex booted (boot status: %#x)\n", - mc_fw_boot_status); - - if (mc_fw_boot_status != 0x1) { - /* - * TODO: Identify critical errors from the GSR register's FS - * field and for those errors, set error to -ENODEV or other - * appropriate errno, so that the status property is set to - * failure in the fsl,dprc device tree node. - */ - } - -out: - if (error != 0) - mc_boot_status = -error; - else - mc_boot_status = 0; - - return error; -} - -int get_mc_boot_status(void) -{ - return mc_boot_status; -} - -/** - * Return the actual size of the MC private DRAM block. - * - * NOTE: For now this function always returns the minimum required size, - * However, in the future, the actual size may be obtained from an environment - * variable. - */ -unsigned long mc_get_dram_block_size(void) -{ - return CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE; -} diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 55f4c963608..17a1cde0399 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -207,12 +207,10 @@ #define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024) #define CONFIG_SYS_LS_MC_FW_IN_NOR #define CONFIG_SYS_LS_MC_FW_ADDR 0x580200000ULL -/* TODO Actual FW length needs to be determined at runtime from FW header */ -#define CONFIG_SYS_LS_MC_FW_LENGTH (4U * 1024 * 1024) #define CONFIG_SYS_LS_MC_DPL_IN_NOR #define CONFIG_SYS_LS_MC_DPL_ADDR 0x5806C0000ULL /* TODO Actual DPL max length needs to be confirmed with the MC FW team */ -#define CONFIG_SYS_LS_MC_DPL_LENGTH 4096 +#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH (256 * 1024) #define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0xe00000 /* Carve the MC private DRAM block from the end of DRAM */ diff --git a/include/fsl-mc/fsl_dpmng.h b/include/fsl-mc/fsl_dpmng.h new file mode 100644 index 00000000000..c2e1ddd18b9 --- /dev/null +++ b/include/fsl-mc/fsl_dpmng.h @@ -0,0 +1,121 @@ +/* Copyright 2014 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/*! + * @file fsl_dpmng.h + * @brief Management Complex General API + */ + +#ifndef __FSL_DPMNG_H +#define __FSL_DPMNG_H + +/*! + * @Group grp_dpmng Management Complex General API + * + * @brief Contains general API for the Management Complex firmware + * @{ + */ + +struct fsl_mc_io; + +/** + * @brief Management Complex firmware version information + */ +#define MC_VER_MAJOR 4 +#define MC_VER_MINOR 0 + +struct mc_version { + uint32_t major; + /*!< Major version number: incremented on API compatibility changes */ + uint32_t minor; + /*!< Minor version number: incremented on API additions (that are + * backward compatible); reset when major version is incremented + */ + uint32_t revision; + /*!< Internal revision number: incremented on implementation changes + * and/or bug fixes that have no impact on API + */ +}; + +/** + * @brief Retrieves the Management Complex firmware version information + * + * @param[in] mc_io Pointer to opaque I/O object + * @param[out] mc_ver_info Pointer to version information structure + * + * @returns '0' on Success; Error code otherwise. + */ +int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info); + +/** + * @brief Resets an AIOP tile + * + * @param[in] mc_io Pointer to opaque I/O object + * @param[in] container_id AIOP container ID + * @param[in] aiop_tile_id AIOP tile ID to reset + * + * @returns '0' on Success; Error code otherwise. + */ +int dpmng_reset_aiop(struct fsl_mc_io *mc_io, + int container_id, + int aiop_tile_id); + +/** + * @brief Loads an image to AIOP tile + * + * @param[in] mc_io Pointer to opaque I/O object + * @param[in] container_id AIOP container ID + * @param[in] aiop_tile_id AIOP tile ID to reset + * @param[in] img_iova I/O virtual address of AIOP ELF image + * @param[in] img_size Size of AIOP ELF image in memory (in bytes) + * + * @returns '0' on Success; Error code otherwise. + */ +int dpmng_load_aiop(struct fsl_mc_io *mc_io, + int container_id, + int aiop_tile_id, + uint64_t img_iova, + uint32_t img_size); + +/** + * @brief AIOP run configuration + */ +struct dpmng_aiop_run_cfg { + uint32_t cores_mask; + /*!< Mask of AIOP cores to run (core 0 in most significant bit) */ + uint64_t options; + /*!< Execution options (currently none defined) */ +}; + +/** + * @brief Starts AIOP tile execution + * + * @param[in] mc_io Pointer to MC portal's I/O object + * @param[in] container_id AIOP container ID + * @param[in] aiop_tile_id AIOP tile ID to reset + * @param[in] cfg AIOP run configuration + * + * @returns '0' on Success; Error code otherwise. + */ +int dpmng_run_aiop(struct fsl_mc_io *mc_io, + int container_id, + int aiop_tile_id, + const struct dpmng_aiop_run_cfg *cfg); + +/** + * @brief Resets MC portal + * + * This function closes all object handles (tokens) that are currently + * open in the MC portal on which the command is submitted. This allows + * cleanup of stale handles that belong to non-functional user processes. + * + * @param[in] mc_io Pointer to MC portal's I/O object + * + * @returns '0' on Success; Error code otherwise. + */ +int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io); + +/** @} */ + +#endif /* __FSL_DPMNG_H */ diff --git a/include/fsl-mc/fsl_mc.h b/include/fsl-mc/fsl_mc.h new file mode 100644 index 00000000000..b9f089e5f32 --- /dev/null +++ b/include/fsl-mc/fsl_mc.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_MC_H__ +#define __FSL_MC_H__ + +#include + +#define MC_CCSR_BASE_ADDR \ + ((struct mc_ccsr_registers __iomem *)0x8340000) + +#define BIT(x) (1 << (x)) +#define GCR1_P1_STOP BIT(31) +#define GCR1_P2_STOP BIT(30) +#define GCR1_P1_DE_RST BIT(23) +#define GCR1_P2_DE_RST BIT(22) +#define GCR1_M1_DE_RST BIT(15) +#define GCR1_M2_DE_RST BIT(14) +#define GCR1_M_ALL_DE_RST (GCR1_M1_DE_RST | GCR1_M2_DE_RST) +#define GSR_FS_MASK 0x3fffffff +#define MCFAPR_PL_MASK (0x1 << 18) +#define MCFAPR_BMT_MASK (0x1 << 17) +#define MCFAPR_BYPASS_ICID_MASK \ + (MCFAPR_PL_MASK | MCFAPR_BMT_MASK) + +#define SOC_MC_PORTALS_BASE_ADDR ((void __iomem *)0x00080C000000) +#define SOC_MC_PORTAL_STRIDE 0x10000 + +#define SOC_MC_PORTAL_ADDR(_portal_id) \ + ((void __iomem *)((uintptr_t)SOC_MC_PORTALS_BASE_ADDR + \ + (_portal_id) * SOC_MC_PORTAL_STRIDE)) + +struct mc_ccsr_registers { + u32 reg_gcr1; + u32 reserved1; + u32 reg_gsr; + u32 reserved2; + u32 reg_sicbalr; + u32 reg_sicbahr; + u32 reg_sicapr; + u32 reserved3; + u32 reg_mcfbalr; + u32 reg_mcfbahr; + u32 reg_mcfapr; + u32 reserved4[0x2f1]; + u32 reg_psr; + u32 reserved5; + u32 reg_brr[2]; + u32 reserved6[0x80]; + u32 reg_error[]; +}; + +int mc_init(bd_t *bis); + +int get_mc_boot_status(void); +#endif diff --git a/include/fsl-mc/fsl_mc_cmd.h b/include/fsl-mc/fsl_mc_cmd.h new file mode 100644 index 00000000000..e7fcb5b142b --- /dev/null +++ b/include/fsl-mc/fsl_mc_cmd.h @@ -0,0 +1,132 @@ +/* Copyright 2014 Freescale Semiconductor Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __FSL_MC_CMD_H +#define __FSL_MC_CMD_H + +#define MC_CMD_NUM_OF_PARAMS 7 + +#define MAKE_UMASK64(_width) \ + ((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : -1)) + +static inline uint64_t u64_enc(int lsoffset, int width, uint64_t val) +{ + return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset); +} +static inline uint64_t u64_dec(uint64_t val, int lsoffset, int width) +{ + return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width)); +} + +struct mc_command { + uint64_t header; + uint64_t params[MC_CMD_NUM_OF_PARAMS]; +}; + +enum mc_cmd_status { + MC_CMD_STATUS_OK = 0x0, /*!< Completed successfully */ + MC_CMD_STATUS_READY = 0x1, /*!< Ready to be processed */ + MC_CMD_STATUS_AUTH_ERR = 0x3, /*!< Authentication error */ + MC_CMD_STATUS_NO_PRIVILEGE = 0x4, /*!< No privilege */ + MC_CMD_STATUS_DMA_ERR = 0x5, /*!< DMA or I/O error */ + MC_CMD_STATUS_CONFIG_ERR = 0x6, /*!< Configuration error */ + MC_CMD_STATUS_TIMEOUT = 0x7, /*!< Operation timed out */ + MC_CMD_STATUS_NO_RESOURCE = 0x8, /*!< No resources */ + MC_CMD_STATUS_NO_MEMORY = 0x9, /*!< No memory available */ + MC_CMD_STATUS_BUSY = 0xA, /*!< Device is busy */ + MC_CMD_STATUS_UNSUPPORTED_OP = 0xB, /*!< Unsupported operation */ + MC_CMD_STATUS_INVALID_STATE = 0xC /*!< Invalid state */ +}; + +#define MC_CMD_HDR_CMDID_O 52 /* Command ID field offset */ +#define MC_CMD_HDR_CMDID_S 12 /* Command ID field size */ +#define MC_CMD_HDR_AUTHID_O 38 /* Authentication ID field offset */ +#define MC_CMD_HDR_AUTHID_S 10 /* Authentication ID field size */ +#define MC_CMD_HDR_STATUS_O 16 /* Status field offset */ +#define MC_CMD_HDR_STATUS_S 8 /* Status field size*/ +#define MC_CMD_HDR_PRI_O 15 /* Priority field offset */ +#define MC_CMD_HDR_PRI_S 1 /* Priority field size */ + +#define MC_CMD_HDR_READ_STATUS(_hdr) \ + ((enum mc_cmd_status)u64_dec((_hdr), \ + MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S)) + +#define MC_CMD_HDR_READ_AUTHID(_hdr) \ + ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S)) + +#define MC_CMD_PRI_LOW 0 /*!< Low Priority command indication */ +#define MC_CMD_PRI_HIGH 1 /*!< High Priority command indication */ + +#define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \ + ((_cmd).params[_param] |= u64_enc((_offset), (_width), _arg)) + +#define MC_RSP_OP(_cmd, _param, _offset, _width, _type, _arg) \ + (_arg = (_type)u64_dec(_cmd.params[_param], (_offset), (_width))) + +static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id, + uint8_t priority, + uint16_t auth_id) +{ + uint64_t hdr; + + hdr = u64_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id); + hdr |= u64_enc(MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S, auth_id); + hdr |= u64_enc(MC_CMD_HDR_PRI_O, MC_CMD_HDR_PRI_S, priority); + hdr |= u64_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S, + MC_CMD_STATUS_READY); + + return hdr; +} + +/** + * mc_write_command - writes a command to a Management Complex (MC) portal + * + * @portal: pointer to an MC portal + * @cmd: pointer to a filled command + */ +static inline void mc_write_command(struct mc_command __iomem *portal, + struct mc_command *cmd) +{ + int i; + + /* copy command parameters into the portal */ + for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++) + writeq(cmd->params[i], &portal->params[i]); + + /* submit the command by writing the header */ + writeq(cmd->header, &portal->header); +} + +/** + * mc_read_response - reads the response for the last MC command from a + * Management Complex (MC) portal + * + * @portal: pointer to an MC portal + * @resp: pointer to command response buffer + * + * Returns MC_CMD_STATUS_OK on Success; Error code otherwise. + */ +static inline enum mc_cmd_status mc_read_response( + struct mc_command __iomem *portal, + struct mc_command *resp) +{ + int i; + enum mc_cmd_status status; + + /* Copy command response header from MC portal: */ + resp->header = readq(&portal->header); + status = MC_CMD_HDR_READ_STATUS(resp->header); + if (status != MC_CMD_STATUS_OK) + return status; + + /* Copy command response data from MC portal: */ + for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++) + resp->params[i] = readq(&portal->params[i]); + + return status; +} + +int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd); + +#endif /* __FSL_MC_CMD_H */ diff --git a/include/fsl-mc/fsl_mc_sys.h b/include/fsl-mc/fsl_mc_sys.h new file mode 100644 index 00000000000..c0befe01d28 --- /dev/null +++ b/include/fsl-mc/fsl_mc_sys.h @@ -0,0 +1,26 @@ +/* + * Freescale Layerscape Management Complex (MC) Environment-specific code + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _FSL_MC_SYS_H +#define _FSL_MC_SYS_H + +#include + +struct mc_command; + +/* + * struct mc_portal_wrapper - MC command portal wrapper object + */ +struct fsl_mc_io { + struct mc_command __iomem *mmio_regs; +}; + +int mc_send_command(struct fsl_mc_io *mc_io, + struct mc_command *cmd); + +#endif /* _FSL_MC_SYS_H */ diff --git a/include/fsl_mc.h b/include/fsl_mc.h deleted file mode 100644 index b9f089e5f32..00000000000 --- a/include/fsl_mc.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2014 Freescale Semiconductor - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __FSL_MC_H__ -#define __FSL_MC_H__ - -#include - -#define MC_CCSR_BASE_ADDR \ - ((struct mc_ccsr_registers __iomem *)0x8340000) - -#define BIT(x) (1 << (x)) -#define GCR1_P1_STOP BIT(31) -#define GCR1_P2_STOP BIT(30) -#define GCR1_P1_DE_RST BIT(23) -#define GCR1_P2_DE_RST BIT(22) -#define GCR1_M1_DE_RST BIT(15) -#define GCR1_M2_DE_RST BIT(14) -#define GCR1_M_ALL_DE_RST (GCR1_M1_DE_RST | GCR1_M2_DE_RST) -#define GSR_FS_MASK 0x3fffffff -#define MCFAPR_PL_MASK (0x1 << 18) -#define MCFAPR_BMT_MASK (0x1 << 17) -#define MCFAPR_BYPASS_ICID_MASK \ - (MCFAPR_PL_MASK | MCFAPR_BMT_MASK) - -#define SOC_MC_PORTALS_BASE_ADDR ((void __iomem *)0x00080C000000) -#define SOC_MC_PORTAL_STRIDE 0x10000 - -#define SOC_MC_PORTAL_ADDR(_portal_id) \ - ((void __iomem *)((uintptr_t)SOC_MC_PORTALS_BASE_ADDR + \ - (_portal_id) * SOC_MC_PORTAL_STRIDE)) - -struct mc_ccsr_registers { - u32 reg_gcr1; - u32 reserved1; - u32 reg_gsr; - u32 reserved2; - u32 reg_sicbalr; - u32 reg_sicbahr; - u32 reg_sicapr; - u32 reserved3; - u32 reg_mcfbalr; - u32 reg_mcfbahr; - u32 reg_mcfapr; - u32 reserved4[0x2f1]; - u32 reg_psr; - u32 reserved5; - u32 reg_brr[2]; - u32 reserved6[0x80]; - u32 reg_error[]; -}; - -int mc_init(bd_t *bis); - -int get_mc_boot_status(void); -#endif -- cgit v1.3.1 From 180b8688dca2a7731a291a7660ae188e6eec84b8 Mon Sep 17 00:00:00 2001 From: Minghuan Lian Date: Wed, 21 Jan 2015 17:29:19 +0800 Subject: arm/ls1021a: add PCIe settings The patch enables and adds PCIe settings for boards LS1021AQDS and LS1021ATWR. Signed-off-by: Minghuan Lian Reviewed-by: York Sun --- include/configs/ls1021aqds.h | 24 ++++++++++++++++++++++++ include/configs/ls1021atwr.h | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) (limited to 'include') diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h index 2874ccc6fad..3dc4da391b3 100644 --- a/include/configs/ls1021aqds.h +++ b/include/configs/ls1021aqds.h @@ -510,6 +510,30 @@ unsigned long get_board_ddr_clk(void); #define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */ #define FSL_PCIE_COMPAT "fsl,ls1021a-pcie" +#define CONFIG_SYS_PCI_64BIT + +#define CONFIG_SYS_PCIE_CFG0_PHYS_OFF 0x00000000 +#define CONFIG_SYS_PCIE_CFG0_SIZE 0x00001000 /* 4k */ +#define CONFIG_SYS_PCIE_CFG1_PHYS_OFF 0x00001000 +#define CONFIG_SYS_PCIE_CFG1_SIZE 0x00001000 /* 4k */ + +#define CONFIG_SYS_PCIE_IO_BUS 0x00000000 +#define CONFIG_SYS_PCIE_IO_PHYS_OFF 0x00010000 +#define CONFIG_SYS_PCIE_IO_SIZE 0x00010000 /* 64k */ + +#define CONFIG_SYS_PCIE_MEM_BUS 0x08000000 +#define CONFIG_SYS_PCIE_MEM_PHYS_OFF 0x04000000 +#define CONFIG_SYS_PCIE_MEM_SIZE 0x08000000 /* 128M */ + +#ifdef CONFIG_PCI +#define CONFIG_NET_MULTI +#define CONFIG_PCI_PNP +#define CONFIG_E1000 +#define CONFIG_PCI_SCAN_SHOW +#define CONFIG_CMD_PCI +#define CONFIG_CMD_NET +#endif + #define CONFIG_CMD_PING #define CONFIG_CMD_DHCP #define CONFIG_CMD_MII diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h index 0a0bb5f1099..a13876b5501 100644 --- a/include/configs/ls1021atwr.h +++ b/include/configs/ls1021atwr.h @@ -303,6 +303,30 @@ #define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */ #define FSL_PCIE_COMPAT "fsl,ls1021a-pcie" +#define CONFIG_SYS_PCI_64BIT + +#define CONFIG_SYS_PCIE_CFG0_PHYS_OFF 0x00000000 +#define CONFIG_SYS_PCIE_CFG0_SIZE 0x00001000 /* 4k */ +#define CONFIG_SYS_PCIE_CFG1_PHYS_OFF 0x00001000 +#define CONFIG_SYS_PCIE_CFG1_SIZE 0x00001000 /* 4k */ + +#define CONFIG_SYS_PCIE_IO_BUS 0x00000000 +#define CONFIG_SYS_PCIE_IO_PHYS_OFF 0x00010000 +#define CONFIG_SYS_PCIE_IO_SIZE 0x00010000 /* 64k */ + +#define CONFIG_SYS_PCIE_MEM_BUS 0x08000000 +#define CONFIG_SYS_PCIE_MEM_PHYS_OFF 0x04000000 +#define CONFIG_SYS_PCIE_MEM_SIZE 0x08000000 /* 128M */ + +#ifdef CONFIG_PCI +#define CONFIG_NET_MULTI +#define CONFIG_PCI_PNP +#define CONFIG_E1000 +#define CONFIG_PCI_SCAN_SHOW +#define CONFIG_CMD_PCI +#define CONFIG_CMD_NET +#endif + #define CONFIG_CMD_PING #define CONFIG_CMD_DHCP #define CONFIG_CMD_MII -- cgit v1.3.1 From 0e1bf614d5045b060db8e1bf9e7f69afdf1c592f Mon Sep 17 00:00:00 2001 From: Volodymyr Riazantsev Date: Tue, 20 Jan 2015 10:16:44 -0500 Subject: mmc: fsl_esdhc: Add support for DDR mode Add support of the DDR mode for eSDHC driver. Enable it for i.MX6 SoC family only. Signed-off-by: Volodymyr Riazantsev Reviewed-by: York Sun --- drivers/mmc/fsl_esdhc.c | 8 ++++++-- include/configs/mx6_common.h | 2 ++ include/fsl_esdhc.h | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index c55eb28217b..f5d2ccba159 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -319,7 +319,8 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) esdhc_write32(®s->cmdarg, cmd->cmdarg); #if defined(CONFIG_FSL_USDHC) esdhc_write32(®s->mixctrl, - (esdhc_read32(®s->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F)); + (esdhc_read32(®s->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F) + | (mmc->ddr_mode ? XFERTYP_DDREN : 0)); esdhc_write32(®s->xfertyp, xfertyp & 0xFFFF0000); #else esdhc_write32(®s->xfertyp, xfertyp); @@ -442,7 +443,7 @@ static void set_sysctl(struct mmc *mmc, uint clock) if ((sdhc_clk / (div * pre_div)) <= clock) break; - pre_div >>= 1; + pre_div >>= mmc->ddr_mode ? 2 : 1; div -= 1; clk = (pre_div << 8) | (div << 4); @@ -601,6 +602,9 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) } cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC; +#ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE + cfg->cfg.host_caps |= MMC_MODE_DDR_52MHz; +#endif if (cfg->max_bus_width > 0) { if (cfg->max_bus_width < 8) diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h index e0528ce4b92..29b72b2e9dd 100644 --- a/include/configs/mx6_common.h +++ b/include/configs/mx6_common.h @@ -28,6 +28,8 @@ #define CONFIG_SYS_PL310_BASE L2_PL310_BASE #endif +#define CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE + #define CONFIG_MP #define CONFIG_MXC_GPT_HCLK diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h index c1b6648591e..313fa1e312a 100644 --- a/include/fsl_esdhc.h +++ b/include/fsl_esdhc.h @@ -108,6 +108,7 @@ #define XFERTYP_RSPTYP_48_BUSY 0x00030000 #define XFERTYP_MSBSEL 0x00000020 #define XFERTYP_DTDSEL 0x00000010 +#define XFERTYP_DDREN 0x00000008 #define XFERTYP_AC12EN 0x00000004 #define XFERTYP_BCEN 0x00000002 #define XFERTYP_DMAEN 0x00000001 -- cgit v1.3.1 From 94e3c8c4fd7bfe395fa467973cd647551d6d98c7 Mon Sep 17 00:00:00 2001 From: gaurav rana Date: Fri, 20 Feb 2015 12:51:46 +0530 Subject: crypto/fsl - Add progressive hashing support using hardware acceleration. Currently only normal hashing is supported using hardware acceleration. Added support for progressive hashing using hardware. Signed-off-by: Ruchika Gupta Signed-off-by: Gaurav Rana CC: Simon Glass Reviewed-by: Simon Glass Reviewed-by: York Sun --- Kconfig | 4 +- README | 20 ++++-- common/hash.c | 10 +++ drivers/crypto/fsl/fsl_hash.c | 138 +++++++++++++++++++++++++++++++++++++++++- drivers/crypto/fsl/fsl_hash.h | 34 +++++++++++ include/fsl_sec.h | 26 ++++++++ include/hw_sha.h | 41 ++++++++++++- lib/Kconfig | 36 +++++++++++ 8 files changed, 302 insertions(+), 7 deletions(-) create mode 100644 drivers/crypto/fsl/fsl_hash.h (limited to 'include') diff --git a/Kconfig b/Kconfig index 75bab7f6cc0..fb012cfb3eb 100644 --- a/Kconfig +++ b/Kconfig @@ -141,7 +141,9 @@ config FIT_SIGNATURE select RSA help This option enables signature verification of FIT uImages, - using a hash signed and verified using RSA. + using a hash signed and verified using RSA. If + CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive + hashing is available using hardware, RSA library will use it. See doc/uImage.FIT/signature.txt for more details. config SYS_EXTRA_OPTIONS diff --git a/README b/README index 6800b959ca5..febefb50c24 100644 --- a/README +++ b/README @@ -3152,8 +3152,18 @@ CBFS (Coreboot Filesystem) support Enable the hash verify command (hash -v). This adds to code size a little. - CONFIG_SHA1 - support SHA1 hashing - CONFIG_SHA256 - support SHA256 hashing + CONFIG_SHA1 - This option enables support of hashing using SHA1 + algorithm. The hash is calculated in software. + CONFIG_SHA256 - This option enables support of hashing using + SHA256 algorithm. The hash is calculated in software. + CONFIG_SHA_HW_ACCEL - This option enables hardware acceleration + for SHA1/SHA256 hashing. + This affects the 'hash' command and also the + hash_lookup_algo() function. + CONFIG_SHA_PROG_HW_ACCEL - This option enables + hardware-acceleration for SHA1/SHA256 progressive hashing. + Data can be streamed in a block at a time and the hashing + is performed in hardware. Note: There is also a sha1sum command, which should perhaps be deprecated in favour of 'hash sha1'. @@ -3447,8 +3457,10 @@ FIT uImage format: CONFIG_FIT_SIGNATURE This option enables signature verification of FIT uImages, - using a hash signed and verified using RSA. See - doc/uImage.FIT/signature.txt for more details. + using a hash signed and verified using RSA. If + CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive + hashing is available using hardware, RSA library will use it. + See doc/uImage.FIT/signature.txt for more details. WARNING: When relying on signed FIT images with required signature check the legacy image format is default diff --git a/common/hash.c b/common/hash.c index d154d029e9c..9e9f84b9fb4 100644 --- a/common/hash.c +++ b/common/hash.c @@ -127,11 +127,21 @@ static struct hash_algo hash_algo[] = { SHA1_SUM_LEN, hw_sha1, CHUNKSZ_SHA1, +#ifdef CONFIG_SHA_PROG_HW_ACCEL + hw_sha_init, + hw_sha_update, + hw_sha_finish, +#endif }, { "sha256", SHA256_SUM_LEN, hw_sha256, CHUNKSZ_SHA256, +#ifdef CONFIG_SHA_PROG_HW_ACCEL + hw_sha_init, + hw_sha_update, + hw_sha_finish, +#endif }, #endif #ifdef CONFIG_SHA1 diff --git a/drivers/crypto/fsl/fsl_hash.c b/drivers/crypto/fsl/fsl_hash.c index d77f2573d0f..c298404f252 100644 --- a/drivers/crypto/fsl/fsl_hash.c +++ b/drivers/crypto/fsl/fsl_hash.c @@ -10,6 +10,9 @@ #include "jobdesc.h" #include "desc.h" #include "jr.h" +#include "fsl_hash.h" +#include +#include #define CRYPTO_MAX_ALG_NAME 80 #define SHA1_DIGEST_SIZE 20 @@ -39,6 +42,122 @@ static struct caam_hash_template driver_hash[] = { }, }; +static enum caam_hash_algos get_hash_type(struct hash_algo *algo) +{ + if (!strcmp(algo->name, driver_hash[SHA1].name)) + return SHA1; + else + return SHA256; +} + +/* Create the context for progressive hashing using h/w acceleration. + * + * @ctxp: Pointer to the pointer of the context for hashing + * @caam_algo: Enum for SHA1 or SHA256 + * @return 0 if ok, -ENOMEM on error + */ +static int caam_hash_init(void **ctxp, enum caam_hash_algos caam_algo) +{ + *ctxp = calloc(1, sizeof(struct sha_ctx)); + if (*ctxp == NULL) { + debug("Cannot allocate memory for context\n"); + return -ENOMEM; + } + return 0; +} + +/* + * Update sg table for progressive hashing using h/w acceleration + * + * The context is freed by this function if an error occurs. + * We support at most 32 Scatter/Gather Entries. + * + * @hash_ctx: Pointer to the context for hashing + * @buf: Pointer to the buffer being hashed + * @size: Size of the buffer being hashed + * @is_last: 1 if this is the last update; 0 otherwise + * @caam_algo: Enum for SHA1 or SHA256 + * @return 0 if ok, -EINVAL on error + */ +static int caam_hash_update(void *hash_ctx, const void *buf, + unsigned int size, int is_last, + enum caam_hash_algos caam_algo) +{ + uint32_t final = 0; + dma_addr_t addr = virt_to_phys((void *)buf); + struct sha_ctx *ctx = hash_ctx; + + if (ctx->sg_num >= MAX_SG_32) { + free(ctx); + return -EINVAL; + } + +#ifdef CONFIG_PHYS_64BIT + ctx->sg_tbl[ctx->sg_num].addr_hi = addr >> 32; +#else + ctx->sg_tbl[ctx->sg_num].addr_hi = 0x0; +#endif + ctx->sg_tbl[ctx->sg_num].addr_lo = addr; + + sec_out32(&ctx->sg_tbl[ctx->sg_num].len_flag, + (size & SG_ENTRY_LENGTH_MASK)); + + ctx->sg_num++; + + if (is_last) { + final = sec_in32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag) | + SG_ENTRY_FINAL_BIT; + sec_out32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag, final); + } + + return 0; +} + +/* + * Perform progressive hashing on the given buffer and copy hash at + * destination buffer + * + * The context is freed after completion of hash operation. + * + * @hash_ctx: Pointer to the context for hashing + * @dest_buf: Pointer to the destination buffer where hash is to be copied + * @size: Size of the buffer being hashed + * @caam_algo: Enum for SHA1 or SHA256 + * @return 0 if ok, -EINVAL on error + */ +static int caam_hash_finish(void *hash_ctx, void *dest_buf, + int size, enum caam_hash_algos caam_algo) +{ + uint32_t len = 0; + struct sha_ctx *ctx = hash_ctx; + int i = 0, ret = 0; + + if (size < driver_hash[caam_algo].digestsize) { + free(ctx); + return -EINVAL; + } + + for (i = 0; i < ctx->sg_num; i++) + len += (sec_in32(&ctx->sg_tbl[i].len_flag) & + SG_ENTRY_LENGTH_MASK); + + inline_cnstr_jobdesc_hash(ctx->sha_desc, (uint8_t *)ctx->sg_tbl, len, + ctx->hash, + driver_hash[caam_algo].alg_type, + driver_hash[caam_algo].digestsize, + 1); + + ret = run_descriptor_jr(ctx->sha_desc); + + if (ret) + debug("Error %x\n", ret); + else + memcpy(dest_buf, ctx->hash, sizeof(ctx->hash)); + + free(ctx); + return ret; +} + int caam_hash(const unsigned char *pbuf, unsigned int buf_len, unsigned char *pout, enum caam_hash_algos algo) { @@ -48,7 +167,7 @@ int caam_hash(const unsigned char *pbuf, unsigned int buf_len, desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE); if (!desc) { debug("Not enough memory for descriptor allocation\n"); - return -1; + return -ENOMEM; } inline_cnstr_jobdesc_hash(desc, pbuf, buf_len, pout, @@ -75,3 +194,20 @@ void hw_sha1(const unsigned char *pbuf, unsigned int buf_len, if (caam_hash(pbuf, buf_len, pout, SHA1)) printf("CAAM was not setup properly or it is faulty\n"); } + +int hw_sha_init(struct hash_algo *algo, void **ctxp) +{ + return caam_hash_init(ctxp, get_hash_type(algo)); +} + +int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf, + unsigned int size, int is_last) +{ + return caam_hash_update(ctx, buf, size, is_last, get_hash_type(algo)); +} + +int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf, + int size) +{ + return caam_hash_finish(ctx, dest_buf, size, get_hash_type(algo)); +} diff --git a/drivers/crypto/fsl/fsl_hash.h b/drivers/crypto/fsl/fsl_hash.h new file mode 100644 index 00000000000..f5be651d7af --- /dev/null +++ b/drivers/crypto/fsl/fsl_hash.h @@ -0,0 +1,34 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + */ + +#ifndef _SHA_H +#define _SHA_H + +#include +#include +#include "jr.h" + +/* We support at most 32 Scatter/Gather Entries.*/ +#define MAX_SG_32 32 + +/* + * Hash context contains the following fields + * @sha_desc: Sha Descriptor + * @sg_num: number of entries in sg table + * @len: total length of buffer + * @sg_tbl: sg entry table + * @hash: index to the hash calculated + */ +struct sha_ctx { + uint32_t sha_desc[64]; + uint32_t sg_num; + uint32_t len; + struct sg_entry sg_tbl[MAX_SG_32]; + u8 hash[HASH_MAX_DIGEST_SIZE]; +}; + +#endif diff --git a/include/fsl_sec.h b/include/fsl_sec.h index aa850a3bf13..b6e6f04a34c 100644 --- a/include/fsl_sec.h +++ b/include/fsl_sec.h @@ -175,6 +175,32 @@ struct jr_regs { u32 jrcr; }; +/* + * Scatter Gather Entry - Specifies the the Scatter Gather Format + * related information + */ +struct sg_entry { +#ifdef CONFIG_SYS_FSL_SEC_LE + uint32_t addr_lo; /* Memory Address - lo */ + uint16_t addr_hi; /* Memory Address of start of buffer - hi */ + uint16_t reserved_zero; +#else + uint16_t reserved_zero; + uint16_t addr_hi; /* Memory Address of start of buffer - hi */ + uint32_t addr_lo; /* Memory Address - lo */ +#endif + + uint32_t len_flag; /* Length of the data in the frame */ +#define SG_ENTRY_LENGTH_MASK 0x3FFFFFFF +#define SG_ENTRY_EXTENSION_BIT 0x80000000 +#define SG_ENTRY_FINAL_BIT 0x40000000 + uint32_t bpid_offset; +#define SG_ENTRY_BPID_MASK 0x00FF0000 +#define SG_ENTRY_BPID_SHIFT 16 +#define SG_ENTRY_OFFSET_MASK 0x00001FFF +#define SG_ENTRY_OFFSET_SHIFT 0 +}; + int sec_init(void); #endif diff --git a/include/hw_sha.h b/include/hw_sha.h index 783350d5136..ab19a991889 100644 --- a/include/hw_sha.h +++ b/include/hw_sha.h @@ -7,7 +7,7 @@ */ #ifndef __HW_SHA_H #define __HW_SHA_H - +#include /** * Computes hash value of input pbuf using h/w acceleration @@ -34,4 +34,43 @@ void hw_sha256(const uchar * in_addr, uint buflen, */ void hw_sha1(const uchar * in_addr, uint buflen, uchar * out_addr, uint chunk_size); + +/* + * Create the context for sha progressive hashing using h/w acceleration + * + * @algo: Pointer to the hash_algo struct + * @ctxp: Pointer to the pointer of the context for hashing + * @return 0 if ok, -ve on error + */ +int hw_sha_init(struct hash_algo *algo, void **ctxp); + +/* + * Update buffer for sha progressive hashing using h/w acceleration + * + * The context is freed by this function if an error occurs. + * + * @algo: Pointer to the hash_algo struct + * @ctx: Pointer to the context for hashing + * @buf: Pointer to the buffer being hashed + * @size: Size of the buffer being hashed + * @is_last: 1 if this is the last update; 0 otherwise + * @return 0 if ok, -ve on error + */ +int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf, + unsigned int size, int is_last); + +/* + * Copy sha hash result at destination location + * + * The context is freed after completion of hash operation or after an error. + * + * @algo: Pointer to the hash_algo struct + * @ctx: Pointer to the context for hashing + * @dest_buf: Pointer to the destination buffer where hash is to be copied + * @size: Size of the buffer being hashed + * @return 0 if ok, -ve on error + */ +int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf, + int size); + #endif diff --git a/lib/Kconfig b/lib/Kconfig index a1f30a2c4ef..c9d2767d1da 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -29,4 +29,40 @@ config SYS_HZ source lib/rsa/Kconfig +menu "Hashing Support" + +config SHA1 + bool "Enable SHA1 support" + help + This option enables support of hashing using SHA1 algorithm. + The hash is calculated in software. + The SHA1 algorithm produces a 160-bit (20-byte) hash value + (digest). + +config SHA256 + bool "Enable SHA256 support" + help + This option enables support of hashing using SHA256 algorithm. + The hash is calculated in software. + The SHA256 algorithm produces a 256-bit (32-byte) hash value + (digest). + +config SHA_HW_ACCEL + bool "Enable hashing using hardware" + help + This option enables hardware acceleration + for SHA1/SHA256 hashing. + This affects the 'hash' command and also the + hash_lookup_algo() function. + +config SHA_PROG_HW_ACCEL + bool "Enable Progressive hashing support using hardware" + depends on SHA_HW_ACCEL + help + This option enables hardware-acceleration for + SHA1/SHA256 progressive hashing. + Data can be streamed in a block at a time and the hashing + is performed in hardware. +endmenu + endmenu -- cgit v1.3.1