xref: /rk3399_rockchip-uboot/arch/arm/mach-uniphier/memconf.c (revision 8197d92843952b376915fdbcbf67c723feab1532)
18d6c99c6SMasahiro Yamada /*
28d6c99c6SMasahiro Yamada  * Copyright (C) 2011-2015 Panasonic Corporation
38d6c99c6SMasahiro Yamada  * Copyright (C) 2016      Socionext Inc.
48d6c99c6SMasahiro Yamada  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
58d6c99c6SMasahiro Yamada  *
68d6c99c6SMasahiro Yamada  * SPDX-License-Identifier:	GPL-2.0+
78d6c99c6SMasahiro Yamada  */
88d6c99c6SMasahiro Yamada 
98d6c99c6SMasahiro Yamada #include <common.h>
100f4ec05bSMasahiro Yamada #include <linux/errno.h>
118d6c99c6SMasahiro Yamada #include <linux/io.h>
128d6c99c6SMasahiro Yamada #include <linux/sizes.h>
138d6c99c6SMasahiro Yamada 
148d6c99c6SMasahiro Yamada #include "sg-regs.h"
158d6c99c6SMasahiro Yamada #include "init.h"
168d6c99c6SMasahiro Yamada 
__uniphier_memconf_init(const struct uniphier_board_data * bd,int have_ch2)178d6c99c6SMasahiro Yamada static int __uniphier_memconf_init(const struct uniphier_board_data *bd,
18*00aa453eSMasahiro Yamada 				   int have_ch2)
198d6c99c6SMasahiro Yamada {
208d6c99c6SMasahiro Yamada 	u32 val = 0;
218d6c99c6SMasahiro Yamada 	unsigned long size_per_word;
228d6c99c6SMasahiro Yamada 
238d6c99c6SMasahiro Yamada 	/* set up ch0 */
248d6c99c6SMasahiro Yamada 	switch (bd->dram_ch[0].width) {
258d6c99c6SMasahiro Yamada 	case 16:
268d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH0_NUM_1;
278d6c99c6SMasahiro Yamada 		size_per_word = bd->dram_ch[0].size;
288d6c99c6SMasahiro Yamada 		break;
298d6c99c6SMasahiro Yamada 	case 32:
308d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH0_NUM_2;
318d6c99c6SMasahiro Yamada 		size_per_word = bd->dram_ch[0].size >> 1;
328d6c99c6SMasahiro Yamada 		break;
338d6c99c6SMasahiro Yamada 	default:
348d6c99c6SMasahiro Yamada 		pr_err("error: unsupported DRAM ch0 width\n");
358d6c99c6SMasahiro Yamada 		return -EINVAL;
368d6c99c6SMasahiro Yamada 	}
378d6c99c6SMasahiro Yamada 
388d6c99c6SMasahiro Yamada 	switch (size_per_word) {
398d6c99c6SMasahiro Yamada 	case SZ_64M:
408d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH0_SZ_64M;
418d6c99c6SMasahiro Yamada 		break;
428d6c99c6SMasahiro Yamada 	case SZ_128M:
438d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH0_SZ_128M;
448d6c99c6SMasahiro Yamada 		break;
458d6c99c6SMasahiro Yamada 	case SZ_256M:
468d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH0_SZ_256M;
478d6c99c6SMasahiro Yamada 		break;
488d6c99c6SMasahiro Yamada 	case SZ_512M:
498d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH0_SZ_512M;
508d6c99c6SMasahiro Yamada 		break;
518d6c99c6SMasahiro Yamada 	case SZ_1G:
528d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH0_SZ_1G;
538d6c99c6SMasahiro Yamada 		break;
548d6c99c6SMasahiro Yamada 	default:
558d6c99c6SMasahiro Yamada 		pr_err("error: unsupported DRAM ch0 size\n");
568d6c99c6SMasahiro Yamada 		return -EINVAL;
578d6c99c6SMasahiro Yamada 	}
588d6c99c6SMasahiro Yamada 
598d6c99c6SMasahiro Yamada 	/* set up ch1 */
608d6c99c6SMasahiro Yamada 	switch (bd->dram_ch[1].width) {
618d6c99c6SMasahiro Yamada 	case 16:
628d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH1_NUM_1;
638d6c99c6SMasahiro Yamada 		size_per_word = bd->dram_ch[1].size;
648d6c99c6SMasahiro Yamada 		break;
658d6c99c6SMasahiro Yamada 	case 32:
668d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH1_NUM_2;
678d6c99c6SMasahiro Yamada 		size_per_word = bd->dram_ch[1].size >> 1;
688d6c99c6SMasahiro Yamada 		break;
698d6c99c6SMasahiro Yamada 	default:
708d6c99c6SMasahiro Yamada 		pr_err("error: unsupported DRAM ch1 width\n");
718d6c99c6SMasahiro Yamada 		return -EINVAL;
728d6c99c6SMasahiro Yamada 	}
738d6c99c6SMasahiro Yamada 
748d6c99c6SMasahiro Yamada 	switch (size_per_word) {
758d6c99c6SMasahiro Yamada 	case SZ_64M:
768d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH1_SZ_64M;
778d6c99c6SMasahiro Yamada 		break;
788d6c99c6SMasahiro Yamada 	case SZ_128M:
798d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH1_SZ_128M;
808d6c99c6SMasahiro Yamada 		break;
818d6c99c6SMasahiro Yamada 	case SZ_256M:
828d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH1_SZ_256M;
838d6c99c6SMasahiro Yamada 		break;
848d6c99c6SMasahiro Yamada 	case SZ_512M:
858d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH1_SZ_512M;
868d6c99c6SMasahiro Yamada 		break;
878d6c99c6SMasahiro Yamada 	case SZ_1G:
888d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH1_SZ_1G;
898d6c99c6SMasahiro Yamada 		break;
908d6c99c6SMasahiro Yamada 	default:
918d6c99c6SMasahiro Yamada 		pr_err("error: unsupported DRAM ch1 size\n");
928d6c99c6SMasahiro Yamada 		return -EINVAL;
938d6c99c6SMasahiro Yamada 	}
948d6c99c6SMasahiro Yamada 
958d6c99c6SMasahiro Yamada 	/* is sparse mem? */
9604cd4e72SMasahiro Yamada 	if (bd->flags & UNIPHIER_BD_DRAM_SPARSE)
978d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_SPARSEMEM;
988d6c99c6SMasahiro Yamada 
998d6c99c6SMasahiro Yamada 	if (!have_ch2)
1008d6c99c6SMasahiro Yamada 		goto out;
1018d6c99c6SMasahiro Yamada 
1028d6c99c6SMasahiro Yamada 	if (!bd->dram_ch[2].size) {
1038d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH2_DISABLE;
1048d6c99c6SMasahiro Yamada 		goto out;
1058d6c99c6SMasahiro Yamada 	}
1068d6c99c6SMasahiro Yamada 
1078d6c99c6SMasahiro Yamada 	/* set up ch2 */
1088d6c99c6SMasahiro Yamada 	switch (bd->dram_ch[2].width) {
1098d6c99c6SMasahiro Yamada 	case 16:
1108d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH2_NUM_1;
1118d6c99c6SMasahiro Yamada 		size_per_word = bd->dram_ch[2].size;
1128d6c99c6SMasahiro Yamada 		break;
1138d6c99c6SMasahiro Yamada 	case 32:
1148d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH2_NUM_2;
1158d6c99c6SMasahiro Yamada 		size_per_word = bd->dram_ch[2].size >> 1;
1168d6c99c6SMasahiro Yamada 		break;
1178d6c99c6SMasahiro Yamada 	default:
1188d6c99c6SMasahiro Yamada 		pr_err("error: unsupported DRAM ch2 width\n");
1198d6c99c6SMasahiro Yamada 		return -EINVAL;
1208d6c99c6SMasahiro Yamada 	}
1218d6c99c6SMasahiro Yamada 
1228d6c99c6SMasahiro Yamada 	switch (size_per_word) {
1238d6c99c6SMasahiro Yamada 	case SZ_64M:
1248d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH2_SZ_64M;
1258d6c99c6SMasahiro Yamada 		break;
1268d6c99c6SMasahiro Yamada 	case SZ_128M:
1278d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH2_SZ_128M;
1288d6c99c6SMasahiro Yamada 		break;
1298d6c99c6SMasahiro Yamada 	case SZ_256M:
1308d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH2_SZ_256M;
1318d6c99c6SMasahiro Yamada 		break;
1328d6c99c6SMasahiro Yamada 	case SZ_512M:
1338d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH2_SZ_512M;
1348d6c99c6SMasahiro Yamada 		break;
1358d6c99c6SMasahiro Yamada 	case SZ_1G:
1368d6c99c6SMasahiro Yamada 		val |= SG_MEMCONF_CH2_SZ_1G;
1378d6c99c6SMasahiro Yamada 		break;
1388d6c99c6SMasahiro Yamada 	default:
1398d6c99c6SMasahiro Yamada 		pr_err("error: unsupported DRAM ch2 size\n");
1408d6c99c6SMasahiro Yamada 		return -EINVAL;
1418d6c99c6SMasahiro Yamada 	}
1428d6c99c6SMasahiro Yamada 
1438d6c99c6SMasahiro Yamada out:
1448d6c99c6SMasahiro Yamada 	writel(val, SG_MEMCONF);
1458d6c99c6SMasahiro Yamada 
1468d6c99c6SMasahiro Yamada 	return 0;
1478d6c99c6SMasahiro Yamada }
1488d6c99c6SMasahiro Yamada 
uniphier_memconf_2ch_init(const struct uniphier_board_data * bd)1498d6c99c6SMasahiro Yamada int uniphier_memconf_2ch_init(const struct uniphier_board_data *bd)
1508d6c99c6SMasahiro Yamada {
151*00aa453eSMasahiro Yamada 	return __uniphier_memconf_init(bd, 0);
1528d6c99c6SMasahiro Yamada }
1538d6c99c6SMasahiro Yamada 
uniphier_memconf_3ch_init(const struct uniphier_board_data * bd)1548d6c99c6SMasahiro Yamada int uniphier_memconf_3ch_init(const struct uniphier_board_data *bd)
1558d6c99c6SMasahiro Yamada {
156*00aa453eSMasahiro Yamada 	return __uniphier_memconf_init(bd, 1);
1578d6c99c6SMasahiro Yamada }
158