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