1 /* 2 * (C) Copyright 2009 3 * Marvell Semiconductor <www.marvell.com> 4 * Written-by: Prafulla Wadaskar <prafulla@marvell.com> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <config.h> 10 #include <common.h> 11 #include <asm/io.h> 12 #include <asm/arch/cpu.h> 13 #include <asm/arch/soc.h> 14 15 #ifdef CONFIG_SYS_MVEBU_DDR_A38X 16 #include "../../../drivers/ddr/marvell/axp/xor.h" 17 #include "../../../drivers/ddr/marvell/axp/xor_regs.h" 18 #endif 19 #ifdef CONFIG_SYS_MVEBU_DDR_AXP 20 #include "../../../drivers/ddr/marvell/axp/xor.h" 21 #include "../../../drivers/ddr/marvell/axp/xor_regs.h" 22 #endif 23 24 DECLARE_GLOBAL_DATA_PTR; 25 26 struct sdram_bank { 27 u32 win_bar; 28 u32 win_sz; 29 }; 30 31 struct sdram_addr_dec { 32 struct sdram_bank sdram_bank[4]; 33 }; 34 35 #define REG_CPUCS_WIN_ENABLE (1 << 0) 36 #define REG_CPUCS_WIN_WR_PROTECT (1 << 1) 37 #define REG_CPUCS_WIN_WIN0_CS(x) (((x) & 0x3) << 2) 38 #define REG_CPUCS_WIN_SIZE(x) (((x) & 0xff) << 24) 39 40 #define SDRAM_SIZE_MAX 0xc0000000 41 42 #define SCRUB_MAGIC 0xbeefdead 43 44 #define SCRB_XOR_UNIT 0 45 #define SCRB_XOR_CHAN 1 46 #define SCRB_XOR_WIN 0 47 48 #define XEBARX_BASE_OFFS 16 49 50 /* 51 * mvebu_sdram_bar - reads SDRAM Base Address Register 52 */ 53 u32 mvebu_sdram_bar(enum memory_bank bank) 54 { 55 struct sdram_addr_dec *base = 56 (struct sdram_addr_dec *)MVEBU_SDRAM_BASE; 57 u32 result = 0; 58 u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz); 59 60 if ((!enable) || (bank > BANK3)) 61 return 0; 62 63 result = readl(&base->sdram_bank[bank].win_bar); 64 return result; 65 } 66 67 /* 68 * mvebu_sdram_bs_set - writes SDRAM Bank size 69 */ 70 static void mvebu_sdram_bs_set(enum memory_bank bank, u32 size) 71 { 72 struct sdram_addr_dec *base = 73 (struct sdram_addr_dec *)MVEBU_SDRAM_BASE; 74 /* Read current register value */ 75 u32 reg = readl(&base->sdram_bank[bank].win_sz); 76 77 /* Clear window size */ 78 reg &= ~REG_CPUCS_WIN_SIZE(0xFF); 79 80 /* Set new window size */ 81 reg |= REG_CPUCS_WIN_SIZE((size - 1) >> 24); 82 83 writel(reg, &base->sdram_bank[bank].win_sz); 84 } 85 86 /* 87 * mvebu_sdram_bs - reads SDRAM Bank size 88 */ 89 u32 mvebu_sdram_bs(enum memory_bank bank) 90 { 91 struct sdram_addr_dec *base = 92 (struct sdram_addr_dec *)MVEBU_SDRAM_BASE; 93 u32 result = 0; 94 u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz); 95 96 if ((!enable) || (bank > BANK3)) 97 return 0; 98 result = 0xff000000 & readl(&base->sdram_bank[bank].win_sz); 99 result += 0x01000000; 100 return result; 101 } 102 103 void mvebu_sdram_size_adjust(enum memory_bank bank) 104 { 105 u32 size; 106 107 /* probe currently equipped RAM size */ 108 size = get_ram_size((void *)mvebu_sdram_bar(bank), 109 mvebu_sdram_bs(bank)); 110 111 /* adjust SDRAM window size accordingly */ 112 mvebu_sdram_bs_set(bank, size); 113 } 114 115 #if defined(CONFIG_SYS_MVEBU_DDR_A38X) || defined(CONFIG_SYS_MVEBU_DDR_AXP) 116 static u32 xor_ctrl_save; 117 static u32 xor_base_save; 118 static u32 xor_mask_save; 119 120 static void mv_xor_init2(u32 cs) 121 { 122 u32 reg, base, size, base2; 123 u32 bank_attr[4] = { 0xe00, 0xd00, 0xb00, 0x700 }; 124 125 xor_ctrl_save = reg_read(XOR_WINDOW_CTRL_REG(SCRB_XOR_UNIT, 126 SCRB_XOR_CHAN)); 127 xor_base_save = reg_read(XOR_BASE_ADDR_REG(SCRB_XOR_UNIT, 128 SCRB_XOR_WIN)); 129 xor_mask_save = reg_read(XOR_SIZE_MASK_REG(SCRB_XOR_UNIT, 130 SCRB_XOR_WIN)); 131 132 /* Enable Window x for each CS */ 133 reg = 0x1; 134 reg |= (0x3 << 16); 135 reg_write(XOR_WINDOW_CTRL_REG(SCRB_XOR_UNIT, SCRB_XOR_CHAN), reg); 136 137 base = 0; 138 size = mvebu_sdram_bs(cs) - 1; 139 if (size) { 140 base2 = ((base / (64 << 10)) << XEBARX_BASE_OFFS) | 141 bank_attr[cs]; 142 reg_write(XOR_BASE_ADDR_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN), 143 base2); 144 145 base += size + 1; 146 size = (size / (64 << 10)) << 16; 147 /* Window x - size - 256 MB */ 148 reg_write(XOR_SIZE_MASK_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN), size); 149 } 150 151 mv_xor_hal_init(0); 152 153 return; 154 } 155 156 static void mv_xor_finish2(void) 157 { 158 reg_write(XOR_WINDOW_CTRL_REG(SCRB_XOR_UNIT, SCRB_XOR_CHAN), 159 xor_ctrl_save); 160 reg_write(XOR_BASE_ADDR_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN), 161 xor_base_save); 162 reg_write(XOR_SIZE_MASK_REG(SCRB_XOR_UNIT, SCRB_XOR_WIN), 163 xor_mask_save); 164 } 165 166 static void dram_ecc_scrubbing(void) 167 { 168 int cs; 169 u32 size, temp; 170 u32 total_mem = 0; 171 u64 total; 172 u32 start_addr; 173 174 /* 175 * The DDR training code from the bin_hdr / SPL already 176 * scrubbed the DDR till 0x1000000. And the main U-Boot 177 * is loaded to an address < 0x1000000. So we need to 178 * skip this range to not re-scrub this area again. 179 */ 180 temp = reg_read(REG_SDRAM_CONFIG_ADDR); 181 temp |= (1 << REG_SDRAM_CONFIG_IERR_OFFS); 182 reg_write(REG_SDRAM_CONFIG_ADDR, temp); 183 184 for (cs = 0; cs < CONFIG_NR_DRAM_BANKS; cs++) { 185 size = mvebu_sdram_bs(cs) - 1; 186 if (size == 0) 187 continue; 188 189 total = (u64)size + 1; 190 total_mem += (u32)(total / (1 << 30)); 191 start_addr = 0; 192 mv_xor_init2(cs); 193 194 /* Skip first 16 MiB */ 195 if (0 == cs) { 196 start_addr = 0x1000000; 197 size -= start_addr; 198 } 199 200 mv_xor_mem_init(SCRB_XOR_CHAN, start_addr, size, 201 SCRUB_MAGIC, SCRUB_MAGIC); 202 203 /* Wait for previous transfer completion */ 204 while (mv_xor_state_get(SCRB_XOR_CHAN) != MV_IDLE) 205 ; 206 207 mv_xor_finish2(); 208 } 209 210 temp = reg_read(REG_SDRAM_CONFIG_ADDR); 211 temp &= ~(1 << REG_SDRAM_CONFIG_IERR_OFFS); 212 reg_write(REG_SDRAM_CONFIG_ADDR, temp); 213 } 214 215 static int ecc_enabled(void) 216 { 217 if (reg_read(REG_SDRAM_CONFIG_ADDR) & (1 << REG_SDRAM_CONFIG_ECC_OFFS)) 218 return 1; 219 220 return 0; 221 } 222 #else 223 static void dram_ecc_scrubbing(void) 224 { 225 } 226 227 static int ecc_enabled(void) 228 { 229 return 0; 230 } 231 #endif 232 233 int dram_init(void) 234 { 235 u64 size = 0; 236 int i; 237 238 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 239 /* 240 * It is assumed that all memory banks are consecutive 241 * and without gaps. 242 * If the gap is found, ram_size will be reported for 243 * consecutive memory only 244 */ 245 if (mvebu_sdram_bar(i) != size) 246 break; 247 248 /* 249 * Don't report more than 3GiB of SDRAM, otherwise there is no 250 * address space left for the internal registers etc. 251 */ 252 size += mvebu_sdram_bs(i); 253 if (size > SDRAM_SIZE_MAX) 254 size = SDRAM_SIZE_MAX; 255 } 256 257 for (; i < CONFIG_NR_DRAM_BANKS; i++) { 258 /* If above loop terminated prematurely, we need to set 259 * remaining banks' start address & size as 0. Otherwise other 260 * u-boot functions and Linux kernel gets wrong values which 261 * could result in crash */ 262 gd->bd->bi_dram[i].start = 0; 263 gd->bd->bi_dram[i].size = 0; 264 } 265 266 267 if (ecc_enabled()) 268 dram_ecc_scrubbing(); 269 270 gd->ram_size = size; 271 272 return 0; 273 } 274 275 /* 276 * If this function is not defined here, 277 * board.c alters dram bank zero configuration defined above. 278 */ 279 void dram_init_banksize(void) 280 { 281 u64 size = 0; 282 int i; 283 284 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 285 gd->bd->bi_dram[i].start = mvebu_sdram_bar(i); 286 gd->bd->bi_dram[i].size = mvebu_sdram_bs(i); 287 288 /* Clip the banksize to 1GiB if it exceeds the max size */ 289 size += gd->bd->bi_dram[i].size; 290 if (size > SDRAM_SIZE_MAX) 291 mvebu_sdram_bs_set(i, 0x40000000); 292 } 293 } 294 295 void board_add_ram_info(int use_default) 296 { 297 if (ecc_enabled()) 298 printf(" (ECC"); 299 else 300 printf(" (ECC not"); 301 printf(" enabled)"); 302 } 303