diff options
author | Masahiro Yamada <yamada.masahiro@socionext.com> | 2017-01-15 14:59:04 +0900 |
---|---|---|
committer | Masahiro Yamada <yamada.masahiro@socionext.com> | 2017-01-17 09:00:40 +0900 |
commit | 8d6c99c66f94c78e65fdacca2fb2857101f8a5e7 (patch) | |
tree | 5b299513f0b58bb4232181c5bab2a94f342526fb /arch/arm/mach-uniphier/memconf.c | |
parent | 78c627cf1f808d5ae9240809a81b71903bdf4fe2 (diff) | |
download | u-boot-imx-8d6c99c66f94c78e65fdacca2fb2857101f8a5e7.zip u-boot-imx-8d6c99c66f94c78e65fdacca2fb2857101f8a5e7.tar.gz u-boot-imx-8d6c99c66f94c78e65fdacca2fb2857101f8a5e7.tar.bz2 |
ARM: uniphier: refactor MEMCONF init code
Currently, memconf-sld3.c and memconf-pxs2.c duplicate the code.
There are 3 patterns in terms of MEMCONF init:
- DRAM 2 channels: LD4, sLD8, Pro4, Pro5, LD11
- DRAM 3 channels: sLD3
- DRAM 3 channels (Ch2 is disable by MEMCONF[21]): Pxs2, LD20
All of them can be moved into a single file by a little more
refactoring.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Diffstat (limited to 'arch/arm/mach-uniphier/memconf.c')
-rw-r--r-- | arch/arm/mach-uniphier/memconf.c | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/arch/arm/mach-uniphier/memconf.c b/arch/arm/mach-uniphier/memconf.c new file mode 100644 index 0000000..205ccf1 --- /dev/null +++ b/arch/arm/mach-uniphier/memconf.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2011-2015 Panasonic Corporation + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/sizes.h> + +#include "sg-regs.h" +#include "init.h" + +static int __uniphier_memconf_init(const struct uniphier_board_data *bd, + int have_ch2, int have_ch2_disable_bit) +{ + u32 val = 0; + unsigned long size_per_word; + + /* set up ch0 */ + switch (bd->dram_ch[0].width) { + case 16: + val |= SG_MEMCONF_CH0_NUM_1; + size_per_word = bd->dram_ch[0].size; + break; + case 32: + val |= SG_MEMCONF_CH0_NUM_2; + size_per_word = bd->dram_ch[0].size >> 1; + break; + default: + pr_err("error: unsupported DRAM ch0 width\n"); + return -EINVAL; + } + + switch (size_per_word) { + case SZ_64M: + val |= SG_MEMCONF_CH0_SZ_64M; + break; + case SZ_128M: + val |= SG_MEMCONF_CH0_SZ_128M; + break; + case SZ_256M: + val |= SG_MEMCONF_CH0_SZ_256M; + break; + case SZ_512M: + val |= SG_MEMCONF_CH0_SZ_512M; + break; + case SZ_1G: + val |= SG_MEMCONF_CH0_SZ_1G; + break; + default: + pr_err("error: unsupported DRAM ch0 size\n"); + return -EINVAL; + } + + /* set up ch1 */ + switch (bd->dram_ch[1].width) { + case 16: + val |= SG_MEMCONF_CH1_NUM_1; + size_per_word = bd->dram_ch[1].size; + break; + case 32: + val |= SG_MEMCONF_CH1_NUM_2; + size_per_word = bd->dram_ch[1].size >> 1; + break; + default: + pr_err("error: unsupported DRAM ch1 width\n"); + return -EINVAL; + } + + switch (size_per_word) { + case SZ_64M: + val |= SG_MEMCONF_CH1_SZ_64M; + break; + case SZ_128M: + val |= SG_MEMCONF_CH1_SZ_128M; + break; + case SZ_256M: + val |= SG_MEMCONF_CH1_SZ_256M; + break; + case SZ_512M: + val |= SG_MEMCONF_CH1_SZ_512M; + break; + case SZ_1G: + val |= SG_MEMCONF_CH1_SZ_1G; + break; + default: + pr_err("error: unsupported DRAM ch1 size\n"); + return -EINVAL; + } + + /* is sparse mem? */ + if (bd->dram_ch[0].base + bd->dram_ch[0].size < bd->dram_ch[1].base) + val |= SG_MEMCONF_SPARSEMEM; + + if (!have_ch2) + goto out; + + if (!bd->dram_ch[2].size) { + if (have_ch2_disable_bit) + val |= SG_MEMCONF_CH2_DISABLE; + goto out; + } + + /* set up ch2 */ + switch (bd->dram_ch[2].width) { + case 16: + val |= SG_MEMCONF_CH2_NUM_1; + size_per_word = bd->dram_ch[2].size; + break; + case 32: + val |= SG_MEMCONF_CH2_NUM_2; + size_per_word = bd->dram_ch[2].size >> 1; + break; + default: + pr_err("error: unsupported DRAM ch2 width\n"); + return -EINVAL; + } + + switch (size_per_word) { + case SZ_64M: + val |= SG_MEMCONF_CH2_SZ_64M; + break; + case SZ_128M: + val |= SG_MEMCONF_CH2_SZ_128M; + break; + case SZ_256M: + val |= SG_MEMCONF_CH2_SZ_256M; + break; + case SZ_512M: + val |= SG_MEMCONF_CH2_SZ_512M; + break; + case SZ_1G: + val |= SG_MEMCONF_CH2_SZ_1G; + break; + default: + pr_err("error: unsupported DRAM ch2 size\n"); + return -EINVAL; + } + +out: + writel(val, SG_MEMCONF); + + return 0; +} + +int uniphier_memconf_2ch_init(const struct uniphier_board_data *bd) +{ + return __uniphier_memconf_init(bd, 0, 0); +} + +int uniphier_memconf_3ch_no_disbit_init(const struct uniphier_board_data *bd) +{ + return __uniphier_memconf_init(bd, 1, 0); +} + +int uniphier_memconf_3ch_init(const struct uniphier_board_data *bd) +{ + return __uniphier_memconf_init(bd, 1, 1); +} |