2 * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
4 * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
11 #include <platform_def.h>
13 #include <arch_helpers.h>
14 #include <common/debug.h>
15 #include <drivers/st/stm32mp1_ddr.h>
16 #include <drivers/st/stm32mp1_ddr_helpers.h>
17 #include <drivers/st/stm32mp1_ram.h>
20 #define DDR_PATTERN 0xAAAAAAAAU
21 #define DDR_ANTIPATTERN 0x55555555U
23 static struct ddr_info ddr_priv_data
;
25 int stm32mp1_ddr_clk_enable(struct ddr_info
*priv
, uint32_t mem_speed
)
27 unsigned long ddrphy_clk
, ddr_clk
, mem_speed_hz
;
31 ddrphy_clk
= stm32mp_clk_get_rate(DDRPHYC
);
33 VERBOSE("DDR: mem_speed (%d kHz), RCC %ld kHz\n",
34 mem_speed
, ddrphy_clk
/ 1000U);
36 mem_speed_hz
= mem_speed
* 1000U;
38 /* Max 10% frequency delta */
39 if (ddrphy_clk
> mem_speed_hz
) {
40 ddr_clk
= ddrphy_clk
- mem_speed_hz
;
42 ddr_clk
= mem_speed_hz
- ddrphy_clk
;
44 if (ddr_clk
> (mem_speed_hz
/ 10)) {
45 ERROR("DDR expected freq %d kHz, current is %ld kHz\n",
46 mem_speed
, ddrphy_clk
/ 1000U);
52 /*******************************************************************************
53 * This function tests the DDR data bus wiring.
54 * This is inspired from the Data Bus Test algorithm written by Michael Barr
55 * in "Programming Embedded Systems in C and C++" book.
56 * resources.oreilly.com/examples/9781565923546/blob/master/Chapter6/
57 * File: memtest.c - This source code belongs to Public Domain.
58 * Returns 0 if success, and address value else.
59 ******************************************************************************/
60 static uint32_t ddr_test_data_bus(void)
64 for (pattern
= 1U; pattern
!= 0U; pattern
<<= 1) {
65 mmio_write_32(STM32MP_DDR_BASE
, pattern
);
67 if (mmio_read_32(STM32MP_DDR_BASE
) != pattern
) {
68 return (uint32_t)STM32MP_DDR_BASE
;
75 /*******************************************************************************
76 * This function tests the DDR address bus wiring.
77 * This is inspired from the Data Bus Test algorithm written by Michael Barr
78 * in "Programming Embedded Systems in C and C++" book.
79 * resources.oreilly.com/examples/9781565923546/blob/master/Chapter6/
80 * File: memtest.c - This source code belongs to Public Domain.
81 * Returns 0 if success, and address value else.
82 ******************************************************************************/
83 static uint32_t ddr_test_addr_bus(void)
85 uint64_t addressmask
= (ddr_priv_data
.info
.size
- 1U);
87 uint64_t testoffset
= 0;
89 /* Write the default pattern at each of the power-of-two offsets. */
90 for (offset
= sizeof(uint32_t); (offset
& addressmask
) != 0U;
92 mmio_write_32(STM32MP_DDR_BASE
+ (uint32_t)offset
,
96 /* Check for address bits stuck high. */
97 mmio_write_32(STM32MP_DDR_BASE
+ (uint32_t)testoffset
,
100 for (offset
= sizeof(uint32_t); (offset
& addressmask
) != 0U;
102 if (mmio_read_32(STM32MP_DDR_BASE
+ (uint32_t)offset
) !=
104 return (uint32_t)(STM32MP_DDR_BASE
+ offset
);
108 mmio_write_32(STM32MP_DDR_BASE
+ (uint32_t)testoffset
, DDR_PATTERN
);
110 /* Check for address bits stuck low or shorted. */
111 for (testoffset
= sizeof(uint32_t); (testoffset
& addressmask
) != 0U;
113 mmio_write_32(STM32MP_DDR_BASE
+ (uint32_t)testoffset
,
116 if (mmio_read_32(STM32MP_DDR_BASE
) != DDR_PATTERN
) {
117 return STM32MP_DDR_BASE
;
120 for (offset
= sizeof(uint32_t); (offset
& addressmask
) != 0U;
122 if ((mmio_read_32(STM32MP_DDR_BASE
+
123 (uint32_t)offset
) != DDR_PATTERN
) &&
124 (offset
!= testoffset
)) {
125 return (uint32_t)(STM32MP_DDR_BASE
+ offset
);
129 mmio_write_32(STM32MP_DDR_BASE
+ (uint32_t)testoffset
,
136 /*******************************************************************************
137 * This function checks the DDR size. It has to be run with Data Cache off.
138 * This test is run before data have been put in DDR, and is only done for
139 * cold boot. The DDR data can then be overwritten, and it is not useful to
140 * restore its content.
141 * Returns DDR computed size.
142 ******************************************************************************/
143 static uint32_t ddr_check_size(void)
145 uint32_t offset
= sizeof(uint32_t);
147 mmio_write_32(STM32MP_DDR_BASE
, DDR_PATTERN
);
149 while (offset
< STM32MP_DDR_MAX_SIZE
) {
150 mmio_write_32(STM32MP_DDR_BASE
+ offset
, DDR_ANTIPATTERN
);
153 if (mmio_read_32(STM32MP_DDR_BASE
) != DDR_PATTERN
) {
160 INFO("Memory size = 0x%x (%d MB)\n", offset
, offset
/ (1024U * 1024U));
165 static int stm32mp1_ddr_setup(void)
167 struct ddr_info
*priv
= &ddr_priv_data
;
169 struct stm32mp1_ddr_config config
;
171 uint32_t tamp_clk_off
= 0, uret
, idx
;
174 #define PARAM(x, y) \
177 .offset = offsetof(struct stm32mp1_ddr_config, y), \
178 .size = sizeof(config.y) / sizeof(uint32_t) \
181 #define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x)
182 #define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x)
185 const char *name
; /* Name in DT */
186 const uint32_t offset
; /* Offset in config struct */
187 const uint32_t size
; /* Size of parameters */
198 if (fdt_get_address(&fdt
) == 0) {
202 node
= fdt_node_offset_by_compatible(fdt
, -1, DT_DDR_COMPAT
);
204 ERROR("%s: Cannot read DDR node in DT\n", __func__
);
208 config
.info
.speed
= fdt_read_uint32_default(node
, "st,mem-speed", 0);
209 if (!config
.info
.speed
) {
210 VERBOSE("%s: no st,mem-speed\n", __func__
);
213 config
.info
.size
= fdt_read_uint32_default(node
, "st,mem-size", 0);
214 if (!config
.info
.size
) {
215 VERBOSE("%s: no st,mem-size\n", __func__
);
218 config
.info
.name
= fdt_getprop(fdt
, node
, "st,mem-name", &len
);
219 if (config
.info
.name
== NULL
) {
220 VERBOSE("%s: no st,mem-name\n", __func__
);
223 INFO("RAM: %s\n", config
.info
.name
);
225 for (idx
= 0; idx
< ARRAY_SIZE(param
); idx
++) {
226 ret
= fdt_read_uint32_array(node
, param
[idx
].name
,
227 (void *)((uintptr_t)&config
+
231 VERBOSE("%s: %s[0x%x] = %d\n", __func__
,
232 param
[idx
].name
, param
[idx
].size
, ret
);
234 ERROR("%s: Cannot read %s\n",
235 __func__
, param
[idx
].name
);
240 if (!stm32mp_clk_is_enabled(RTCAPB
)) {
242 if (stm32mp_clk_enable(RTCAPB
) != 0) {
247 if (tamp_clk_off
!= 0U) {
248 if (stm32mp_clk_disable(RTCAPB
) != 0) {
253 /* Disable axidcg clock gating during init */
254 mmio_clrbits_32(priv
->rcc
+ RCC_DDRITFCR
, RCC_DDRITFCR_AXIDCGEN
);
256 stm32mp1_ddr_init(priv
, &config
);
258 /* Enable axidcg clock gating */
259 mmio_setbits_32(priv
->rcc
+ RCC_DDRITFCR
, RCC_DDRITFCR_AXIDCGEN
);
261 priv
->info
.size
= config
.info
.size
;
263 VERBOSE("%s : ram size(%x, %x)\n", __func__
,
264 (uint32_t)priv
->info
.base
, (uint32_t)priv
->info
.size
);
266 write_sctlr(read_sctlr() & ~SCTLR_C_BIT
);
267 dcsw_op_all(DC_OP_CISW
);
269 uret
= ddr_test_data_bus();
271 ERROR("DDR data bus test: can't access memory @ 0x%x\n",
276 uret
= ddr_test_addr_bus();
278 ERROR("DDR addr bus test: can't access memory @ 0x%x\n",
283 uret
= ddr_check_size();
284 if (uret
< config
.info
.size
) {
285 ERROR("DDR size: 0x%x does not match DT config: 0x%x\n",
286 uret
, config
.info
.size
);
290 write_sctlr(read_sctlr() | SCTLR_C_BIT
);
295 int stm32mp1_ddr_probe(void)
297 struct ddr_info
*priv
= &ddr_priv_data
;
299 VERBOSE("STM32MP DDR probe\n");
301 priv
->ctl
= (struct stm32mp1_ddrctl
*)DDRCTRL_BASE
;
302 priv
->phy
= (struct stm32mp1_ddrphy
*)DDRPHYC_BASE
;
303 priv
->pwr
= PWR_BASE
;
304 priv
->rcc
= RCC_BASE
;
306 priv
->info
.base
= STM32MP_DDR_BASE
;
309 return stm32mp1_ddr_setup();