]>
Commit | Line | Data |
---|---|---|
8d6c99c6 MY |
1 | /* |
2 | * Copyright (C) 2011-2015 Panasonic Corporation | |
3 | * Copyright (C) 2016 Socionext Inc. | |
4 | * Author: Masahiro Yamada <yamada.masahiro@socionext.com> | |
5 | * | |
6 | * SPDX-License-Identifier: GPL-2.0+ | |
7 | */ | |
8 | ||
9 | #include <common.h> | |
0f4ec05b | 10 | #include <linux/errno.h> |
8d6c99c6 MY |
11 | #include <linux/io.h> |
12 | #include <linux/sizes.h> | |
13 | ||
14 | #include "sg-regs.h" | |
15 | #include "init.h" | |
16 | ||
17 | static int __uniphier_memconf_init(const struct uniphier_board_data *bd, | |
00aa453e | 18 | int have_ch2) |
8d6c99c6 MY |
19 | { |
20 | u32 val = 0; | |
21 | unsigned long size_per_word; | |
22 | ||
23 | /* set up ch0 */ | |
24 | switch (bd->dram_ch[0].width) { | |
25 | case 16: | |
26 | val |= SG_MEMCONF_CH0_NUM_1; | |
27 | size_per_word = bd->dram_ch[0].size; | |
28 | break; | |
29 | case 32: | |
30 | val |= SG_MEMCONF_CH0_NUM_2; | |
31 | size_per_word = bd->dram_ch[0].size >> 1; | |
32 | break; | |
33 | default: | |
34 | pr_err("error: unsupported DRAM ch0 width\n"); | |
35 | return -EINVAL; | |
36 | } | |
37 | ||
38 | switch (size_per_word) { | |
39 | case SZ_64M: | |
40 | val |= SG_MEMCONF_CH0_SZ_64M; | |
41 | break; | |
42 | case SZ_128M: | |
43 | val |= SG_MEMCONF_CH0_SZ_128M; | |
44 | break; | |
45 | case SZ_256M: | |
46 | val |= SG_MEMCONF_CH0_SZ_256M; | |
47 | break; | |
48 | case SZ_512M: | |
49 | val |= SG_MEMCONF_CH0_SZ_512M; | |
50 | break; | |
51 | case SZ_1G: | |
52 | val |= SG_MEMCONF_CH0_SZ_1G; | |
53 | break; | |
54 | default: | |
55 | pr_err("error: unsupported DRAM ch0 size\n"); | |
56 | return -EINVAL; | |
57 | } | |
58 | ||
59 | /* set up ch1 */ | |
60 | switch (bd->dram_ch[1].width) { | |
61 | case 16: | |
62 | val |= SG_MEMCONF_CH1_NUM_1; | |
63 | size_per_word = bd->dram_ch[1].size; | |
64 | break; | |
65 | case 32: | |
66 | val |= SG_MEMCONF_CH1_NUM_2; | |
67 | size_per_word = bd->dram_ch[1].size >> 1; | |
68 | break; | |
69 | default: | |
70 | pr_err("error: unsupported DRAM ch1 width\n"); | |
71 | return -EINVAL; | |
72 | } | |
73 | ||
74 | switch (size_per_word) { | |
75 | case SZ_64M: | |
76 | val |= SG_MEMCONF_CH1_SZ_64M; | |
77 | break; | |
78 | case SZ_128M: | |
79 | val |= SG_MEMCONF_CH1_SZ_128M; | |
80 | break; | |
81 | case SZ_256M: | |
82 | val |= SG_MEMCONF_CH1_SZ_256M; | |
83 | break; | |
84 | case SZ_512M: | |
85 | val |= SG_MEMCONF_CH1_SZ_512M; | |
86 | break; | |
87 | case SZ_1G: | |
88 | val |= SG_MEMCONF_CH1_SZ_1G; | |
89 | break; | |
90 | default: | |
91 | pr_err("error: unsupported DRAM ch1 size\n"); | |
92 | return -EINVAL; | |
93 | } | |
94 | ||
95 | /* is sparse mem? */ | |
04cd4e72 | 96 | if (bd->flags & UNIPHIER_BD_DRAM_SPARSE) |
8d6c99c6 MY |
97 | val |= SG_MEMCONF_SPARSEMEM; |
98 | ||
99 | if (!have_ch2) | |
100 | goto out; | |
101 | ||
102 | if (!bd->dram_ch[2].size) { | |
00aa453e | 103 | val |= SG_MEMCONF_CH2_DISABLE; |
8d6c99c6 MY |
104 | goto out; |
105 | } | |
106 | ||
107 | /* set up ch2 */ | |
108 | switch (bd->dram_ch[2].width) { | |
109 | case 16: | |
110 | val |= SG_MEMCONF_CH2_NUM_1; | |
111 | size_per_word = bd->dram_ch[2].size; | |
112 | break; | |
113 | case 32: | |
114 | val |= SG_MEMCONF_CH2_NUM_2; | |
115 | size_per_word = bd->dram_ch[2].size >> 1; | |
116 | break; | |
117 | default: | |
118 | pr_err("error: unsupported DRAM ch2 width\n"); | |
119 | return -EINVAL; | |
120 | } | |
121 | ||
122 | switch (size_per_word) { | |
123 | case SZ_64M: | |
124 | val |= SG_MEMCONF_CH2_SZ_64M; | |
125 | break; | |
126 | case SZ_128M: | |
127 | val |= SG_MEMCONF_CH2_SZ_128M; | |
128 | break; | |
129 | case SZ_256M: | |
130 | val |= SG_MEMCONF_CH2_SZ_256M; | |
131 | break; | |
132 | case SZ_512M: | |
133 | val |= SG_MEMCONF_CH2_SZ_512M; | |
134 | break; | |
135 | case SZ_1G: | |
136 | val |= SG_MEMCONF_CH2_SZ_1G; | |
137 | break; | |
138 | default: | |
139 | pr_err("error: unsupported DRAM ch2 size\n"); | |
140 | return -EINVAL; | |
141 | } | |
142 | ||
143 | out: | |
144 | writel(val, SG_MEMCONF); | |
145 | ||
146 | return 0; | |
147 | } | |
148 | ||
149 | int uniphier_memconf_2ch_init(const struct uniphier_board_data *bd) | |
150 | { | |
00aa453e | 151 | return __uniphier_memconf_init(bd, 0); |
8d6c99c6 MY |
152 | } |
153 | ||
154 | int uniphier_memconf_3ch_init(const struct uniphier_board_data *bd) | |
155 | { | |
00aa453e | 156 | return __uniphier_memconf_init(bd, 1); |
8d6c99c6 | 157 | } |