blob: 3b34e4d372946bd08ad63544723c3511a2a61626 [file] [log] [blame]
Masahiro Yamada8d6c99c2017-01-15 14:59:04 +09001/*
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>
Masahiro Yamada0f4ec052017-01-21 18:05:24 +090010#include <linux/errno.h>
Masahiro Yamada8d6c99c2017-01-15 14:59:04 +090011#include <linux/io.h>
12#include <linux/sizes.h>
13
14#include "sg-regs.h"
15#include "init.h"
16
17static int __uniphier_memconf_init(const struct uniphier_board_data *bd,
Masahiro Yamada00aa4532017-08-13 09:01:13 +090018 int have_ch2)
Masahiro Yamada8d6c99c2017-01-15 14:59:04 +090019{
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? */
Masahiro Yamada04cd4e72017-02-05 10:52:12 +090096 if (bd->flags & UNIPHIER_BD_DRAM_SPARSE)
Masahiro Yamada8d6c99c2017-01-15 14:59:04 +090097 val |= SG_MEMCONF_SPARSEMEM;
98
99 if (!have_ch2)
100 goto out;
101
102 if (!bd->dram_ch[2].size) {
Masahiro Yamada00aa4532017-08-13 09:01:13 +0900103 val |= SG_MEMCONF_CH2_DISABLE;
Masahiro Yamada8d6c99c2017-01-15 14:59:04 +0900104 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
143out:
144 writel(val, SG_MEMCONF);
145
146 return 0;
147}
148
149int uniphier_memconf_2ch_init(const struct uniphier_board_data *bd)
150{
Masahiro Yamada00aa4532017-08-13 09:01:13 +0900151 return __uniphier_memconf_init(bd, 0);
Masahiro Yamada8d6c99c2017-01-15 14:59:04 +0900152}
153
154int uniphier_memconf_3ch_init(const struct uniphier_board_data *bd)
155{
Masahiro Yamada00aa4532017-08-13 09:01:13 +0900156 return __uniphier_memconf_init(bd, 1);
Masahiro Yamada8d6c99c2017-01-15 14:59:04 +0900157}