blob: 600dc0914ae9921cae441a8fad339921cf8e0a42 [file] [log] [blame]
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +02001/*
2 * (C) Copyright 2009
3 * Marvell Semiconductor <www.marvell.com>
4 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
5 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +02007 */
8
9#include <config.h>
Prafulla Wadaskarbeeb2582010-09-30 19:33:19 +053010#include <common.h>
Lei Wena7efd712011-10-18 20:11:42 +053011#include <asm/io.h>
12#include <asm/arch/cpu.h>
Stefan Roese3dc23f72014-10-22 12:13:06 +020013#include <asm/arch/soc.h>
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +020014
Stefan Roese8a83c652015-08-03 13:15:31 +020015#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
Prafulla Wadaskarbeeb2582010-09-30 19:33:19 +053022DECLARE_GLOBAL_DATA_PTR;
23
Stefan Roese96c5f082014-10-22 12:13:13 +020024struct sdram_bank {
Holger Brunckcf37c5d2012-07-20 02:34:24 +000025 u32 win_bar;
26 u32 win_sz;
27};
28
Stefan Roese96c5f082014-10-22 12:13:13 +020029struct sdram_addr_dec {
30 struct sdram_bank sdram_bank[4];
Holger Brunckcf37c5d2012-07-20 02:34:24 +000031};
32
Stefan Roese96c5f082014-10-22 12:13:13 +020033#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)
Gerlando Falauto45515162012-07-20 02:34:25 +000037
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +020038/*
Stefan Roese96c5f082014-10-22 12:13:13 +020039 * mvebu_sdram_bar - reads SDRAM Base Address Register
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +020040 */
Stefan Roese96c5f082014-10-22 12:13:13 +020041u32 mvebu_sdram_bar(enum memory_bank bank)
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +020042{
Stefan Roese96c5f082014-10-22 12:13:13 +020043 struct sdram_addr_dec *base =
44 (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +020045 u32 result = 0;
Holger Brunckcf37c5d2012-07-20 02:34:24 +000046 u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz);
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +020047
48 if ((!enable) || (bank > BANK3))
49 return 0;
50
Holger Brunckcf37c5d2012-07-20 02:34:24 +000051 result = readl(&base->sdram_bank[bank].win_bar);
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +020052 return result;
53}
54
55/*
Stefan Roese96c5f082014-10-22 12:13:13 +020056 * mvebu_sdram_bs_set - writes SDRAM Bank size
Gerlando Falauto45515162012-07-20 02:34:25 +000057 */
Stefan Roese96c5f082014-10-22 12:13:13 +020058static void mvebu_sdram_bs_set(enum memory_bank bank, u32 size)
Gerlando Falauto45515162012-07-20 02:34:25 +000059{
Stefan Roese96c5f082014-10-22 12:13:13 +020060 struct sdram_addr_dec *base =
61 (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
Gerlando Falauto45515162012-07-20 02:34:25 +000062 /* Read current register value */
63 u32 reg = readl(&base->sdram_bank[bank].win_sz);
64
65 /* Clear window size */
Stefan Roese96c5f082014-10-22 12:13:13 +020066 reg &= ~REG_CPUCS_WIN_SIZE(0xFF);
Gerlando Falauto45515162012-07-20 02:34:25 +000067
68 /* Set new window size */
Stefan Roese96c5f082014-10-22 12:13:13 +020069 reg |= REG_CPUCS_WIN_SIZE((size - 1) >> 24);
Gerlando Falauto45515162012-07-20 02:34:25 +000070
71 writel(reg, &base->sdram_bank[bank].win_sz);
72}
73
74/*
Stefan Roese96c5f082014-10-22 12:13:13 +020075 * mvebu_sdram_bs - reads SDRAM Bank size
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +020076 */
Stefan Roese96c5f082014-10-22 12:13:13 +020077u32 mvebu_sdram_bs(enum memory_bank bank)
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +020078{
Stefan Roese96c5f082014-10-22 12:13:13 +020079 struct sdram_addr_dec *base =
80 (struct sdram_addr_dec *)MVEBU_SDRAM_BASE;
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +020081 u32 result = 0;
Holger Brunckcf37c5d2012-07-20 02:34:24 +000082 u32 enable = 0x01 & readl(&base->sdram_bank[bank].win_sz);
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +020083
84 if ((!enable) || (bank > BANK3))
85 return 0;
Holger Brunckcf37c5d2012-07-20 02:34:24 +000086 result = 0xff000000 & readl(&base->sdram_bank[bank].win_sz);
Prafulla Wadaskar4efb77d2009-06-20 11:01:53 +020087 result += 0x01000000;
88 return result;
89}
Prafulla Wadaskarbeeb2582010-09-30 19:33:19 +053090
Stefan Roese96c5f082014-10-22 12:13:13 +020091void mvebu_sdram_size_adjust(enum memory_bank bank)
Gerlando Falautob3168f42012-07-25 06:23:48 +000092{
93 u32 size;
94
95 /* probe currently equipped RAM size */
Stefan Roese96c5f082014-10-22 12:13:13 +020096 size = get_ram_size((void *)mvebu_sdram_bar(bank),
97 mvebu_sdram_bs(bank));
Gerlando Falautob3168f42012-07-25 06:23:48 +000098
99 /* adjust SDRAM window size accordingly */
Stefan Roese96c5f082014-10-22 12:13:13 +0200100 mvebu_sdram_bs_set(bank, size);
Gerlando Falautob3168f42012-07-25 06:23:48 +0000101}
102
Prafulla Wadaskarbeeb2582010-09-30 19:33:19 +0530103int dram_init(void)
104{
105 int i;
106
107 gd->ram_size = 0;
108 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
Stefan Roese96c5f082014-10-22 12:13:13 +0200109 gd->bd->bi_dram[i].start = mvebu_sdram_bar(i);
110 gd->bd->bi_dram[i].size = mvebu_sdram_bs(i);
Prafulla Wadaskarbeeb2582010-09-30 19:33:19 +0530111 /*
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
Stefan Roesed80cca22014-10-22 12:13:05 +0200120 /*
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;
Prafulla Wadaskarbeeb2582010-09-30 19:33:19 +0530127
128 }
Tanmay Upadhyay28e57102010-10-28 20:06:22 +0530129
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
Prafulla Wadaskarbeeb2582010-09-30 19:33:19 +0530139 return 0;
140}
141
142/*
143 * If this function is not defined here,
144 * board.c alters dram bank zero configuration defined above.
145 */
146void dram_init_banksize(void)
147{
148 dram_init();
149}
Stefan Roese8a83c652015-08-03 13:15:31 +0200150
151void 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}