1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * DRAM init helper functions
4 *
5 * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
6 */
7
8#include <config.h>
9#include <time.h>
10#include <vsprintf.h>
11#include <asm/barriers.h>
12#include <asm/io.h>
13#include <asm/arch/dram.h>
14
15/*
16 * Wait up to 1s for value to be set in given part of reg.
17 */
18void mctl_await_completion(u32 *reg, u32 mask, u32 val)
19{
20	unsigned long tmo = timer_get_us() + 1000000;
21
22	while ((readl(reg) & mask) != val) {
23		if (timer_get_us() > tmo)
24			panic("Timeout initialising DRAM\n");
25	}
26}
27
28/*
29 * Test if memory at offset matches memory at a certain base
30 *
31 * Note: dsb() is not available on ARMv5 in Thumb mode
32 */
33#ifndef CONFIG_MACH_SUNIV
34bool mctl_mem_matches_base(u32 offset, ulong base)
35{
36	u32 val_base;
37	u32 val_offset;
38	bool ret;
39
40	/* Save original values */
41	val_base = readl(base);
42	val_offset = readl(base + offset);
43
44	/* Try to write different values to RAM at two addresses */
45	writel(0, base);
46	writel(0xaa55aa55, base + offset);
47	dsb();
48	/* Check if the same value is actually observed when reading back */
49	ret = readl(base) == readl(base + offset);
50
51	/* Restore original values */
52	writel(val_base, base);
53	writel(val_offset, base + offset);
54	return ret;
55}
56
57/*
58 * Test if memory at offset matches memory at begin of DRAM
59 */
60bool mctl_mem_matches(u32 offset)
61{
62	return mctl_mem_matches_base(offset, CFG_SYS_SDRAM_BASE);
63}
64#endif
65