summaryrefslogtreecommitdiff
path: root/arch/arm/mach-uniphier/dram_init.c
diff options
context:
space:
mode:
authorMasahiro Yamada <yamada.masahiro@socionext.com>2016-06-17 19:24:29 +0900
committerMasahiro Yamada <yamada.masahiro@socionext.com>2016-06-20 07:15:33 +0900
commit51ea5a060d7bb187d344c9d24b9bfdc7570681df (patch)
tree9596c55a4a74e9b139dbc6d01d5d2d609b7267a1 /arch/arm/mach-uniphier/dram_init.c
parent18c11986674ae917aad2465ef88cbb2c4e92b170 (diff)
ARM: uniphier: reserve memory for DRAM PHY training on PH1-LD20
The DRAM PHY layer on PH1-LD20 is able to calibrate PHY parameters periodically. This compensates for the voltage and temperature deviation and improves the PHY parameter adjustment. Instead, it requires 64 byte scratch memory in each DRAM channel for the dynamic training. The memory regions must be reserved in DT before jumping to the kernel. The scratch area can be anywhere in each DRAM channel, but the DRAM init code in SPL currently assigns it at the end of each channel. So, it makes sense to reserve the regions on run-time by U-Boot instead of statically embedding it in the DT in Linux. Anyway, a boot-loader should know much more about memory initialization than the kernel. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Diffstat (limited to 'arch/arm/mach-uniphier/dram_init.c')
-rw-r--r--arch/arm/mach-uniphier/dram_init.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/arm/mach-uniphier/dram_init.c b/arch/arm/mach-uniphier/dram_init.c
index ef0e2e8f54..489366c63f 100644
--- a/arch/arm/mach-uniphier/dram_init.c
+++ b/arch/arm/mach-uniphier/dram_init.c
@@ -9,6 +9,9 @@
#include <fdtdec.h>
#include <linux/err.h>
+#include "init.h"
+#include "soc-info.h"
+
DECLARE_GLOBAL_DATA_PTR;
static const void *get_memory_reg_prop(const void *fdt, int *lenp)
@@ -81,3 +84,40 @@ void dram_init_banksize(void)
(unsigned long)gd->bd->bi_dram[i].size);
}
}
+
+#ifdef CONFIG_OF_BOARD_SETUP
+/*
+ * The DRAM PHY requires 64 byte scratch area in each DRAM channel
+ * for its dynamic PHY training feature.
+ */
+int ft_board_setup(void *fdt, bd_t *bd)
+{
+ const struct uniphier_board_data *param;
+ unsigned long rsv_addr;
+ const unsigned long rsv_size = 64;
+ int ch, ret;
+
+ if (uniphier_get_soc_type() != SOC_UNIPHIER_LD20)
+ return 0;
+
+ param = uniphier_get_board_param();
+ if (!param) {
+ printf("failed to get board parameter\n");
+ return -ENODEV;
+ }
+
+ for (ch = 0; ch < param->dram_nr_ch; ch++) {
+ rsv_addr = param->dram_ch[ch].base + param->dram_ch[ch].size;
+ rsv_addr -= rsv_size;
+
+ ret = fdt_add_mem_rsv(fdt, rsv_addr, rsv_size);
+ if (ret)
+ return -ENOSPC;
+
+ printf(" Reserved memory region for DRAM PHY training: addr=%lx size=%lx\n",
+ rsv_addr, rsv_size);
+ }
+
+ return 0;
+}
+#endif