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