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