]> git.sur5r.net Git - u-boot/blob - arch/arm/mach-mvebu/dram.c
arm: mvebu: Display ECC enabled / disabled upon bootup
[u-boot] / arch / arm / mach-mvebu / dram.c
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/a38x/ddr3_init.h"
17 #endif
18 #ifdef CONFIG_SYS_MVEBU_DDR_AXP
19 #include "../../../drivers/ddr/marvell/axp/ddr3_init.h"
20 #endif
21
22 DECLARE_GLOBAL_DATA_PTR;
23
24 struct sdram_bank {
25         u32     win_bar;
26         u32     win_sz;
27 };
28
29 struct sdram_addr_dec {
30         struct sdram_bank sdram_bank[4];
31 };
32
33 #define REG_CPUCS_WIN_ENABLE            (1 << 0)
34 #define REG_CPUCS_WIN_WR_PROTECT        (1 << 1)
35 #define REG_CPUCS_WIN_WIN0_CS(x)        (((x) & 0x3) << 2)
36 #define REG_CPUCS_WIN_SIZE(x)           (((x) & 0xff) << 24)
37
38 /*
39  * mvebu_sdram_bar - reads SDRAM Base Address Register
40  */
41 u32 mvebu_sdram_bar(enum memory_bank bank)
42 {
43         struct sdram_addr_dec *base =
44                 (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
45         u32 result = 0;
46         u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz);
47
48         if ((!enable) || (bank > BANK3))
49                 return 0;
50
51         result = readl(&base->sdram_bank[bank].win_bar);
52         return result;
53 }
54
55 /*
56  * mvebu_sdram_bs_set - writes SDRAM Bank size
57  */
58 static void mvebu_sdram_bs_set(enum memory_bank bank, u32 size)
59 {
60         struct sdram_addr_dec *base =
61                 (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
62         /* Read current register value */
63         u32 reg = readl(&base->sdram_bank[bank].win_sz);
64
65         /* Clear window size */
66         reg &= ~REG_CPUCS_WIN_SIZE(0xFF);
67
68         /* Set new window size */
69         reg |= REG_CPUCS_WIN_SIZE((size - 1) >> 24);
70
71         writel(reg, &base->sdram_bank[bank].win_sz);
72 }
73
74 /*
75  * mvebu_sdram_bs - reads SDRAM Bank size
76  */
77 u32 mvebu_sdram_bs(enum memory_bank bank)
78 {
79         struct sdram_addr_dec *base =
80                 (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
81         u32 result = 0;
82         u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz);
83
84         if ((!enable) || (bank > BANK3))
85                 return 0;
86         result = 0xff000000 & readl(&base->sdram_bank[bank].win_sz);
87         result += 0x01000000;
88         return result;
89 }
90
91 void mvebu_sdram_size_adjust(enum memory_bank bank)
92 {
93         u32 size;
94
95         /* probe currently equipped RAM size */
96         size = get_ram_size((void *)mvebu_sdram_bar(bank),
97                             mvebu_sdram_bs(bank));
98
99         /* adjust SDRAM window size accordingly */
100         mvebu_sdram_bs_set(bank, size);
101 }
102
103 int dram_init(void)
104 {
105         int i;
106
107         gd->ram_size = 0;
108         for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
109                 gd->bd->bi_dram[i].start = mvebu_sdram_bar(i);
110                 gd->bd->bi_dram[i].size = mvebu_sdram_bs(i);
111                 /*
112                  * It is assumed that all memory banks are consecutive
113                  * and without gaps.
114                  * If the gap is found, ram_size will be reported for
115                  * consecutive memory only
116                  */
117                 if (gd->bd->bi_dram[i].start != gd->ram_size)
118                         break;
119
120                 /*
121                  * Don't report more than 3GiB of SDRAM, otherwise there is no
122                  * address space left for the internal registers etc.
123                  */
124                 if ((gd->ram_size + gd->bd->bi_dram[i].size != 0) &&
125                     (gd->ram_size + gd->bd->bi_dram[i].size <= (3 << 30)))
126                         gd->ram_size += gd->bd->bi_dram[i].size;
127
128         }
129
130         for (; i < CONFIG_NR_DRAM_BANKS; i++) {
131                 /* If above loop terminated prematurely, we need to set
132                  * remaining banks' start address & size as 0. Otherwise other
133                  * u-boot functions and Linux kernel gets wrong values which
134                  * could result in crash */
135                 gd->bd->bi_dram[i].start = 0;
136                 gd->bd->bi_dram[i].size = 0;
137         }
138
139         return 0;
140 }
141
142 /*
143  * If this function is not defined here,
144  * board.c alters dram bank zero configuration defined above.
145  */
146 void dram_init_banksize(void)
147 {
148         dram_init();
149 }
150
151 void board_add_ram_info(int use_default)
152 {
153         u32 reg;
154
155         reg = reg_read(REG_SDRAM_CONFIG_ADDR);
156         if (reg & (1 << REG_SDRAM_CONFIG_ECC_OFFS))
157                 printf(" (ECC");
158         else
159                 printf(" (ECC not");
160         printf(" enabled)");
161 }