blob: 6744fbda46d0098e73706e90c6d1e3479eeac59b [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Stefan Roese8870e452013-04-09 21:06:08 +00002/*
3 * Copyright 2013 Stefan Roese <sr@denx.de>
Stefan Roese8870e452013-04-09 21:06:08 +00004 */
5
6#include <common.h>
Simon Glass4d72caa2020-05-10 11:40:01 -06007#include <lmb.h>
Jeroen Hofstee5624c6b2014-10-08 22:57:52 +02008#include <asm/arch/sys_proto.h>
Masahiro Yamada1221ce42016-09-21 11:28:55 +09009#include <linux/errno.h>
Stefan Roese8870e452013-04-09 21:06:08 +000010#include <asm/io.h>
Stefano Babic552a8482017-06-29 10:16:06 +020011#include <asm/mach-imx/regs-common.h>
Stefan Roese8870e452013-04-09 21:06:08 +000012
Ye Li528915c2019-01-04 09:10:20 +000013DECLARE_GLOBAL_DATA_PTR;
14
Stefan Roese8870e452013-04-09 21:06:08 +000015/* 1 second delay should be plenty of time for block reset. */
16#define RESET_MAX_TIMEOUT 1000000
17
18#define MXS_BLOCK_SFTRST (1 << 31)
19#define MXS_BLOCK_CLKGATE (1 << 30)
20
21int mxs_wait_mask_set(struct mxs_register_32 *reg, uint32_t mask, unsigned
22 int timeout)
23{
24 while (--timeout) {
25 if ((readl(&reg->reg) & mask) == mask)
26 break;
27 udelay(1);
28 }
29
30 return !timeout;
31}
32
33int mxs_wait_mask_clr(struct mxs_register_32 *reg, uint32_t mask, unsigned
34 int timeout)
35{
36 while (--timeout) {
37 if ((readl(&reg->reg) & mask) == 0)
38 break;
39 udelay(1);
40 }
41
42 return !timeout;
43}
44
45int mxs_reset_block(struct mxs_register_32 *reg)
46{
47 /* Clear SFTRST */
48 writel(MXS_BLOCK_SFTRST, &reg->reg_clr);
49
50 if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
51 return 1;
52
53 /* Clear CLKGATE */
54 writel(MXS_BLOCK_CLKGATE, &reg->reg_clr);
55
56 /* Set SFTRST */
57 writel(MXS_BLOCK_SFTRST, &reg->reg_set);
58
59 /* Wait for CLKGATE being set */
60 if (mxs_wait_mask_set(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
61 return 1;
62
63 /* Clear SFTRST */
64 writel(MXS_BLOCK_SFTRST, &reg->reg_clr);
65
66 if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
67 return 1;
68
69 /* Clear CLKGATE */
70 writel(MXS_BLOCK_CLKGATE, &reg->reg_clr);
71
72 if (mxs_wait_mask_clr(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
73 return 1;
74
75 return 0;
76}
Ye Li528915c2019-01-04 09:10:20 +000077
78static ulong get_sp(void)
79{
80 ulong ret;
81
82 asm("mov %0, sp" : "=r"(ret) : );
83 return ret;
84}
85
86void board_lmb_reserve(struct lmb *lmb)
87{
88 ulong sp, bank_end;
89 int bank;
90
91 sp = get_sp();
92 debug("## Current stack ends at 0x%08lx ", sp);
93
94 /* adjust sp by 16K to be safe */
95 sp -= 4096 << 2;
96 for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
97 if (sp < gd->bd->bi_dram[bank].start)
98 continue;
99 bank_end = gd->bd->bi_dram[bank].start +
100 gd->bd->bi_dram[bank].size;
101 if (sp >= bank_end)
102 continue;
103 lmb_reserve(lmb, sp, bank_end - sp);
104 break;
105 }
106}