xref: /rk3399_ARM-atf/plat/marvell/armada/common/marvell_ddr_info.c (revision a28471722afb3ae784d7bce2118c2ea703f8444c)
1*a2847172SGrzegorz Jaszczyk /*
2*a2847172SGrzegorz Jaszczyk  * Copyright (C) 2018 Marvell International Ltd.
3*a2847172SGrzegorz Jaszczyk  *
4*a2847172SGrzegorz Jaszczyk  * SPDX-License-Identifier:     BSD-3-Clause
5*a2847172SGrzegorz Jaszczyk  * https://spdx.org/licenses
6*a2847172SGrzegorz Jaszczyk  */
7*a2847172SGrzegorz Jaszczyk 
8*a2847172SGrzegorz Jaszczyk #include <platform_def.h>
9*a2847172SGrzegorz Jaszczyk 
10*a2847172SGrzegorz Jaszczyk #include <common/debug.h>
11*a2847172SGrzegorz Jaszczyk #include <lib/mmio.h>
12*a2847172SGrzegorz Jaszczyk 
13*a2847172SGrzegorz Jaszczyk #include <ddr_info.h>
14*a2847172SGrzegorz Jaszczyk 
15*a2847172SGrzegorz Jaszczyk #define DRAM_CH0_MMAP_LOW_REG(iface, cs, base)	\
16*a2847172SGrzegorz Jaszczyk 	(base + DRAM_CH0_MMAP_LOW_OFFSET + (iface) * 0x10000 + (cs) * 0x8)
17*a2847172SGrzegorz Jaszczyk #define DRAM_CH0_MMAP_HIGH_REG(iface, cs, base)	\
18*a2847172SGrzegorz Jaszczyk 	(DRAM_CH0_MMAP_LOW_REG(iface, cs, base) + 4)
19*a2847172SGrzegorz Jaszczyk #define DRAM_CS_VALID_ENABLED_MASK		0x1
20*a2847172SGrzegorz Jaszczyk #define DRAM_AREA_LENGTH_OFFS			16
21*a2847172SGrzegorz Jaszczyk #define DRAM_AREA_LENGTH_MASK			(0x1f << DRAM_AREA_LENGTH_OFFS)
22*a2847172SGrzegorz Jaszczyk #define DRAM_START_ADDRESS_L_OFFS		23
23*a2847172SGrzegorz Jaszczyk #define DRAM_START_ADDRESS_L_MASK		\
24*a2847172SGrzegorz Jaszczyk 					(0x1ff << DRAM_START_ADDRESS_L_OFFS)
25*a2847172SGrzegorz Jaszczyk #define DRAM_START_ADDR_HTOL_OFFS		32
26*a2847172SGrzegorz Jaszczyk 
27*a2847172SGrzegorz Jaszczyk #define DRAM_MAX_CS_NUM				2
28*a2847172SGrzegorz Jaszczyk 
29*a2847172SGrzegorz Jaszczyk #define DRAM_CS_ENABLED(iface, cs, base) \
30*a2847172SGrzegorz Jaszczyk 	(mmio_read_32(DRAM_CH0_MMAP_LOW_REG(iface, cs, base)) & \
31*a2847172SGrzegorz Jaszczyk 	 DRAM_CS_VALID_ENABLED_MASK)
32*a2847172SGrzegorz Jaszczyk #define GET_DRAM_REGION_SIZE_CODE(iface, cs, base) \
33*a2847172SGrzegorz Jaszczyk 	(mmio_read_32(DRAM_CH0_MMAP_LOW_REG(iface, cs, base)) & \
34*a2847172SGrzegorz Jaszczyk 	DRAM_AREA_LENGTH_MASK) >> DRAM_AREA_LENGTH_OFFS
35*a2847172SGrzegorz Jaszczyk 
36*a2847172SGrzegorz Jaszczyk /* Mapping between DDR area length and real DDR size is specific and looks like
37*a2847172SGrzegorz Jaszczyk  * bellow:
38*a2847172SGrzegorz Jaszczyk  * 0 => 384 MB
39*a2847172SGrzegorz Jaszczyk  * 1 => 768 MB
40*a2847172SGrzegorz Jaszczyk  * 2 => 1536 MB
41*a2847172SGrzegorz Jaszczyk  * 3 => 3 GB
42*a2847172SGrzegorz Jaszczyk  * 4 => 6 GB
43*a2847172SGrzegorz Jaszczyk  *
44*a2847172SGrzegorz Jaszczyk  * 7 => 8 MB
45*a2847172SGrzegorz Jaszczyk  * 8 => 16 MB
46*a2847172SGrzegorz Jaszczyk  * 9 => 32 MB
47*a2847172SGrzegorz Jaszczyk  * 10 => 64 MB
48*a2847172SGrzegorz Jaszczyk  * 11 => 128 MB
49*a2847172SGrzegorz Jaszczyk  * 12 => 256 MB
50*a2847172SGrzegorz Jaszczyk  * 13 => 512 MB
51*a2847172SGrzegorz Jaszczyk  * 14 => 1 GB
52*a2847172SGrzegorz Jaszczyk  * 15 => 2 GB
53*a2847172SGrzegorz Jaszczyk  * 16 => 4 GB
54*a2847172SGrzegorz Jaszczyk  * 17 => 8 GB
55*a2847172SGrzegorz Jaszczyk  * 18 => 16 GB
56*a2847172SGrzegorz Jaszczyk  * 19 => 32 GB
57*a2847172SGrzegorz Jaszczyk  * 20 => 64 GB
58*a2847172SGrzegorz Jaszczyk  * 21 => 128 GB
59*a2847172SGrzegorz Jaszczyk  * 22 => 256 GB
60*a2847172SGrzegorz Jaszczyk  * 23 => 512 GB
61*a2847172SGrzegorz Jaszczyk  * 24 => 1 TB
62*a2847172SGrzegorz Jaszczyk  * 25 => 2 TB
63*a2847172SGrzegorz Jaszczyk  * 26 => 4 TB
64*a2847172SGrzegorz Jaszczyk  *
65*a2847172SGrzegorz Jaszczyk  * to calculate real size we need to use two different formulas:
66*a2847172SGrzegorz Jaszczyk  * -- GET_DRAM_REGION_SIZE_ODD for values 0-4 (DRAM_REGION_SIZE_ODD)
67*a2847172SGrzegorz Jaszczyk  * -- GET_DRAM_REGION_SIZE_EVEN for values 7-26 (DRAM_REGION_SIZE_EVEN)
68*a2847172SGrzegorz Jaszczyk  * using mentioned formulas we cover whole mapping between "Area length" value
69*a2847172SGrzegorz Jaszczyk  * and real size (see above mapping).
70*a2847172SGrzegorz Jaszczyk  */
71*a2847172SGrzegorz Jaszczyk #define DRAM_REGION_SIZE_EVEN(C)	(((C) >= 7) && ((C) <= 26))
72*a2847172SGrzegorz Jaszczyk #define GET_DRAM_REGION_SIZE_EVEN(C)	((uint64_t)1 << ((C) + 16))
73*a2847172SGrzegorz Jaszczyk #define DRAM_REGION_SIZE_ODD(C)		((C) <= 4)
74*a2847172SGrzegorz Jaszczyk #define GET_DRAM_REGION_SIZE_ODD(C)	((uint64_t)0x18000000 << (C))
75*a2847172SGrzegorz Jaszczyk 
76*a2847172SGrzegorz Jaszczyk 
77*a2847172SGrzegorz Jaszczyk uint64_t mvebu_get_dram_size(uint64_t ap_base_addr)
78*a2847172SGrzegorz Jaszczyk {
79*a2847172SGrzegorz Jaszczyk 	uint64_t mem_size = 0;
80*a2847172SGrzegorz Jaszczyk 	uint8_t region_code;
81*a2847172SGrzegorz Jaszczyk 	uint8_t cs, iface;
82*a2847172SGrzegorz Jaszczyk 
83*a2847172SGrzegorz Jaszczyk 	for (iface = 0; iface < DRAM_MAX_IFACE; iface++) {
84*a2847172SGrzegorz Jaszczyk 		for (cs = 0; cs < DRAM_MAX_CS_NUM; cs++) {
85*a2847172SGrzegorz Jaszczyk 
86*a2847172SGrzegorz Jaszczyk 			/* Exit loop on first disabled DRAM CS */
87*a2847172SGrzegorz Jaszczyk 			if (!DRAM_CS_ENABLED(iface, cs, ap_base_addr))
88*a2847172SGrzegorz Jaszczyk 				break;
89*a2847172SGrzegorz Jaszczyk 
90*a2847172SGrzegorz Jaszczyk 			/* Decode area length for current CS
91*a2847172SGrzegorz Jaszczyk 			 * from register value
92*a2847172SGrzegorz Jaszczyk 			 */
93*a2847172SGrzegorz Jaszczyk 			region_code =
94*a2847172SGrzegorz Jaszczyk 				GET_DRAM_REGION_SIZE_CODE(iface, cs,
95*a2847172SGrzegorz Jaszczyk 							  ap_base_addr);
96*a2847172SGrzegorz Jaszczyk 
97*a2847172SGrzegorz Jaszczyk 			if (DRAM_REGION_SIZE_EVEN(region_code)) {
98*a2847172SGrzegorz Jaszczyk 				mem_size +=
99*a2847172SGrzegorz Jaszczyk 					GET_DRAM_REGION_SIZE_EVEN(region_code);
100*a2847172SGrzegorz Jaszczyk 			} else if (DRAM_REGION_SIZE_ODD(region_code)) {
101*a2847172SGrzegorz Jaszczyk 				mem_size +=
102*a2847172SGrzegorz Jaszczyk 					GET_DRAM_REGION_SIZE_ODD(region_code);
103*a2847172SGrzegorz Jaszczyk 			} else {
104*a2847172SGrzegorz Jaszczyk 				WARN("%s: Invalid mem region (0x%x) CS#%d\n",
105*a2847172SGrzegorz Jaszczyk 				      __func__, region_code, cs);
106*a2847172SGrzegorz Jaszczyk 				return 0;
107*a2847172SGrzegorz Jaszczyk 			}
108*a2847172SGrzegorz Jaszczyk 		}
109*a2847172SGrzegorz Jaszczyk 	}
110*a2847172SGrzegorz Jaszczyk 
111*a2847172SGrzegorz Jaszczyk 	return mem_size;
112*a2847172SGrzegorz Jaszczyk }
113