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 Yamadastatic 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 Yamadaint 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 Yamadaint uniphier_memconf_3ch_init(const struct uniphier_board_data *bd) 1558d6c99c6SMasahiro Yamada { 156*00aa453eSMasahiro Yamada return __uniphier_memconf_init(bd, 1); 1578d6c99c6SMasahiro Yamada } 158