2 * Copyright (C) 2011-2015 Panasonic Corporation
3 * Copyright (C) 2016 Socionext Inc.
4 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
6 * SPDX-License-Identifier: GPL-2.0+
10 #include <linux/err.h>
12 #include <linux/sizes.h>
17 static int __uniphier_memconf_init(const struct uniphier_board_data *bd,
18 int have_ch2, int have_ch2_disable_bit)
21 unsigned long size_per_word;
24 switch (bd->dram_ch[0].width) {
26 val |= SG_MEMCONF_CH0_NUM_1;
27 size_per_word = bd->dram_ch[0].size;
30 val |= SG_MEMCONF_CH0_NUM_2;
31 size_per_word = bd->dram_ch[0].size >> 1;
34 pr_err("error: unsupported DRAM ch0 width\n");
38 switch (size_per_word) {
40 val |= SG_MEMCONF_CH0_SZ_64M;
43 val |= SG_MEMCONF_CH0_SZ_128M;
46 val |= SG_MEMCONF_CH0_SZ_256M;
49 val |= SG_MEMCONF_CH0_SZ_512M;
52 val |= SG_MEMCONF_CH0_SZ_1G;
55 pr_err("error: unsupported DRAM ch0 size\n");
60 switch (bd->dram_ch[1].width) {
62 val |= SG_MEMCONF_CH1_NUM_1;
63 size_per_word = bd->dram_ch[1].size;
66 val |= SG_MEMCONF_CH1_NUM_2;
67 size_per_word = bd->dram_ch[1].size >> 1;
70 pr_err("error: unsupported DRAM ch1 width\n");
74 switch (size_per_word) {
76 val |= SG_MEMCONF_CH1_SZ_64M;
79 val |= SG_MEMCONF_CH1_SZ_128M;
82 val |= SG_MEMCONF_CH1_SZ_256M;
85 val |= SG_MEMCONF_CH1_SZ_512M;
88 val |= SG_MEMCONF_CH1_SZ_1G;
91 pr_err("error: unsupported DRAM ch1 size\n");
96 if (bd->dram_ch[0].base + bd->dram_ch[0].size < bd->dram_ch[1].base)
97 val |= SG_MEMCONF_SPARSEMEM;
102 if (!bd->dram_ch[2].size) {
103 if (have_ch2_disable_bit)
104 val |= SG_MEMCONF_CH2_DISABLE;
109 switch (bd->dram_ch[2].width) {
111 val |= SG_MEMCONF_CH2_NUM_1;
112 size_per_word = bd->dram_ch[2].size;
115 val |= SG_MEMCONF_CH2_NUM_2;
116 size_per_word = bd->dram_ch[2].size >> 1;
119 pr_err("error: unsupported DRAM ch2 width\n");
123 switch (size_per_word) {
125 val |= SG_MEMCONF_CH2_SZ_64M;
128 val |= SG_MEMCONF_CH2_SZ_128M;
131 val |= SG_MEMCONF_CH2_SZ_256M;
134 val |= SG_MEMCONF_CH2_SZ_512M;
137 val |= SG_MEMCONF_CH2_SZ_1G;
140 pr_err("error: unsupported DRAM ch2 size\n");
145 writel(val, SG_MEMCONF);
150 int uniphier_memconf_2ch_init(const struct uniphier_board_data *bd)
152 return __uniphier_memconf_init(bd, 0, 0);
155 int uniphier_memconf_3ch_no_disbit_init(const struct uniphier_board_data *bd)
157 return __uniphier_memconf_init(bd, 1, 0);
160 int uniphier_memconf_3ch_init(const struct uniphier_board_data *bd)
162 return __uniphier_memconf_init(bd, 1, 1);