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