summaryrefslogtreecommitdiff
path: root/cpu/mpc8xxx/ddr/util.c
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2008-08-26 15:01:29 -0500
committerWolfgang Denk <wd@denx.de>2008-08-27 02:05:58 +0200
commit58e5e9aff147e8c7e2bc1406bf9384f65f020ffa (patch)
treea246c5ded0e1cdc32687c52b15483b11a0966795 /cpu/mpc8xxx/ddr/util.c
parentf784e32b4bce0013983506b11af4b85b8ca3d36e (diff)
downloadu-boot-imx-58e5e9aff147e8c7e2bc1406bf9384f65f020ffa.zip
u-boot-imx-58e5e9aff147e8c7e2bc1406bf9384f65f020ffa.tar.gz
u-boot-imx-58e5e9aff147e8c7e2bc1406bf9384f65f020ffa.tar.bz2
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 <James.Yang@freescale.com> Signed-off-by: Jon Loeliger <jdl@freescale.com> Signed-off-by: Becky Bruce <becky.bruce@freescale.com> Signed-off-by: Ed Swarthout <Ed.Swarthout@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'cpu/mpc8xxx/ddr/util.c')
-rw-r--r--cpu/mpc8xxx/ddr/util.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/cpu/mpc8xxx/ddr/util.c b/cpu/mpc8xxx/ddr/util.c
new file mode 100644
index 0000000..27c135b
--- /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 <common.h>
+#include <asm/fsl_law.h>
+
+#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);