test/py: Add usb gadget binding test
[platform/kernel/u-boot.git] / arch / arm / mach-imx / misc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2013 Stefan Roese <sr@denx.de>
4  */
5
6 #include <common.h>
7 #include <lmb.h>
8 #include <log.h>
9 #include <asm/arch/sys_proto.h>
10 #include <asm/global_data.h>
11 #include <linux/delay.h>
12 #include <linux/errno.h>
13 #include <asm/io.h>
14 #include <asm/mach-imx/regs-common.h>
15
16 DECLARE_GLOBAL_DATA_PTR;
17
18 /* 1 second delay should be plenty of time for block reset. */
19 #define RESET_MAX_TIMEOUT       1000000
20
21 #define MXS_BLOCK_SFTRST        (1 << 31)
22 #define MXS_BLOCK_CLKGATE       (1 << 30)
23
24 int mxs_wait_mask_set(struct mxs_register_32 *reg, uint32_t mask, unsigned
25                                                                 int timeout)
26 {
27         while (--timeout) {
28                 if ((readl(&reg->reg) & mask) == mask)
29                         break;
30                 udelay(1);
31         }
32
33         return !timeout;
34 }
35
36 int mxs_wait_mask_clr(struct mxs_register_32 *reg, uint32_t mask, unsigned
37                                                                 int timeout)
38 {
39         while (--timeout) {
40                 if ((readl(&reg->reg) & mask) == 0)
41                         break;
42                 udelay(1);
43         }
44
45         return !timeout;
46 }
47
48 int mxs_reset_block(struct mxs_register_32 *reg)
49 {
50         /* Clear SFTRST */
51         writel(MXS_BLOCK_SFTRST, &reg->reg_clr);
52
53         if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
54                 return 1;
55
56         /* Clear CLKGATE */
57         writel(MXS_BLOCK_CLKGATE, &reg->reg_clr);
58
59         /* Set SFTRST */
60         writel(MXS_BLOCK_SFTRST, &reg->reg_set);
61
62         /* Wait for CLKGATE being set */
63         if (mxs_wait_mask_set(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
64                 return 1;
65
66         /* Clear SFTRST */
67         writel(MXS_BLOCK_SFTRST, &reg->reg_clr);
68
69         if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
70                 return 1;
71
72         /* Clear CLKGATE */
73         writel(MXS_BLOCK_CLKGATE, &reg->reg_clr);
74
75         if (mxs_wait_mask_clr(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
76                 return 1;
77
78         return 0;
79 }
80
81 static ulong get_sp(void)
82 {
83         ulong ret;
84
85         asm("mov %0, sp" : "=r"(ret) : );
86         return ret;
87 }
88
89 void board_lmb_reserve(struct lmb *lmb)
90 {
91         ulong sp, bank_end;
92         int bank;
93
94         sp = get_sp();
95         debug("## Current stack ends at 0x%08lx ", sp);
96
97         /* adjust sp by 16K to be safe */
98         sp -= 4096 << 2;
99         for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
100                 if (sp < gd->bd->bi_dram[bank].start)
101                         continue;
102                 bank_end = gd->bd->bi_dram[bank].start +
103                         gd->bd->bi_dram[bank].size;
104                 if (sp >= bank_end)
105                         continue;
106                 lmb_reserve(lmb, sp, bank_end - sp);
107                 break;
108         }
109 }