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