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