From 58e5e9aff147e8c7e2bc1406bf9384f65f020ffa Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 26 Aug 2008 15:01:29 -0500 Subject: FSL DDR: Rewrite the FSL mpc8xxx DDR controller setup code. The main purpose of this rewrite it to be able to share the same initialization code on all FSL PowerPC products that have DDR controllers. (83xx, 85xx, 86xx). The code is broken up into the following steps: GET_SPD COMPUTE_DIMM_PARMS COMPUTE_COMMON_PARMS GATHER_OPTS ASSIGN_ADDRESSES COMPUTE_REGS PROGRAM_REGS This allows us to share more code an easily allow for board specific code overrides. Additionally this code base adds support for >4G of DDR and provides a foundation for supporting interleaving on processors with more than one controller. Signed-off-by: James Yang Signed-off-by: Jon Loeliger Signed-off-by: Becky Bruce Signed-off-by: Ed Swarthout Signed-off-by: Kumar Gala --- cpu/mpc8xxx/ddr/util.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 cpu/mpc8xxx/ddr/util.c (limited to 'cpu/mpc8xxx/ddr/util.c') diff --git a/cpu/mpc8xxx/ddr/util.c b/cpu/mpc8xxx/ddr/util.c new file mode 100644 index 00000000000..27c135b112c --- /dev/null +++ b/cpu/mpc8xxx/ddr/util.c @@ -0,0 +1,103 @@ +/* + * Copyright 2008 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * Version 2 as published by the Free Software Foundation. + */ + +#include +#include + +#include "ddr.h" + +unsigned int fsl_ddr_get_mem_data_rate(void); + +/* + * Round mclk_ps to nearest 10 ps in memory controller code. + * + * If an imprecise data rate is too high due to rounding error + * propagation, compute a suitably rounded mclk_ps to compute + * a working memory controller configuration. + */ +unsigned int get_memory_clk_period_ps(void) +{ + unsigned int mclk_ps; + + mclk_ps = 2000000000000ULL / fsl_ddr_get_mem_data_rate(); + /* round to nearest 10 ps */ + return 10 * ((mclk_ps + 5) / 10); +} + +/* Convert picoseconds into DRAM clock cycles (rounding up if needed). */ +unsigned int picos_to_mclk(unsigned int picos) +{ + const unsigned long long ULL_2e12 = 2000000000000ULL; + const unsigned long long ULL_8Fs = 0xFFFFFFFFULL; + unsigned long long clks; + unsigned long long clks_temp; + + if (!picos) + return 0; + + clks = fsl_ddr_get_mem_data_rate() * (unsigned long long) picos; + clks_temp = clks; + clks = clks / ULL_2e12; + if (clks_temp % ULL_2e12) { + clks++; + } + + if (clks > ULL_8Fs) { + clks = ULL_8Fs; + } + + return (unsigned int) clks; +} + +unsigned int mclk_to_picos(unsigned int mclk) +{ + return get_memory_clk_period_ps() * mclk; +} + +void +__fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, + unsigned int memctl_interleaved, + unsigned int ctrl_num) +{ + /* + * If no DIMMs on this controller, do not proceed any further. + */ + if (!memctl_common_params->ndimms_present) { + return; + } + + if (ctrl_num == 0) { + /* + * Set up LAW for DDR controller 1 space. + */ + unsigned int lawbar1_target_id = memctl_interleaved + ? LAW_TRGT_IF_DDR_INTRLV : LAW_TRGT_IF_DDR_1; + + if (set_ddr_laws(memctl_common_params->base_address, + memctl_common_params->total_mem, + lawbar1_target_id) < 0) { + printf("ERROR\n"); + return ; + } + } else if (ctrl_num == 1) { + if (set_ddr_laws(memctl_common_params->base_address, + memctl_common_params->total_mem, + LAW_TRGT_IF_DDR_2) < 0) { + printf("ERROR\n"); + return ; + } + } else { + printf("unexpected controller number %u in %s\n", + ctrl_num, __FUNCTION__); + } +} + +__attribute__((weak, alias("__fsl_ddr_set_lawbar"))) void +fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, + unsigned int memctl_interleaved, + unsigned int ctrl_num); -- cgit v1.2.3