1*552a848eSStefano Babic /*
2*552a848eSStefano Babic * Copyright 2013 Stefan Roese <sr@denx.de>
3*552a848eSStefano Babic *
4*552a848eSStefano Babic * SPDX-License-Identifier: GPL-2.0+
5*552a848eSStefano Babic */
6*552a848eSStefano Babic
7*552a848eSStefano Babic #include <common.h>
8*552a848eSStefano Babic #include <asm/arch/sys_proto.h>
9*552a848eSStefano Babic #include <linux/errno.h>
10*552a848eSStefano Babic #include <asm/io.h>
11*552a848eSStefano Babic #include <asm/mach-imx/regs-common.h>
12*552a848eSStefano Babic
13*552a848eSStefano Babic /* 1 second delay should be plenty of time for block reset. */
14*552a848eSStefano Babic #define RESET_MAX_TIMEOUT 1000000
15*552a848eSStefano Babic
16*552a848eSStefano Babic #define MXS_BLOCK_SFTRST (1 << 31)
17*552a848eSStefano Babic #define MXS_BLOCK_CLKGATE (1 << 30)
18*552a848eSStefano Babic
mxs_wait_mask_set(struct mxs_register_32 * reg,uint32_t mask,unsigned int timeout)19*552a848eSStefano Babic int mxs_wait_mask_set(struct mxs_register_32 *reg, uint32_t mask, unsigned
20*552a848eSStefano Babic int timeout)
21*552a848eSStefano Babic {
22*552a848eSStefano Babic while (--timeout) {
23*552a848eSStefano Babic if ((readl(®->reg) & mask) == mask)
24*552a848eSStefano Babic break;
25*552a848eSStefano Babic udelay(1);
26*552a848eSStefano Babic }
27*552a848eSStefano Babic
28*552a848eSStefano Babic return !timeout;
29*552a848eSStefano Babic }
30*552a848eSStefano Babic
mxs_wait_mask_clr(struct mxs_register_32 * reg,uint32_t mask,unsigned int timeout)31*552a848eSStefano Babic int mxs_wait_mask_clr(struct mxs_register_32 *reg, uint32_t mask, unsigned
32*552a848eSStefano Babic int timeout)
33*552a848eSStefano Babic {
34*552a848eSStefano Babic while (--timeout) {
35*552a848eSStefano Babic if ((readl(®->reg) & mask) == 0)
36*552a848eSStefano Babic break;
37*552a848eSStefano Babic udelay(1);
38*552a848eSStefano Babic }
39*552a848eSStefano Babic
40*552a848eSStefano Babic return !timeout;
41*552a848eSStefano Babic }
42*552a848eSStefano Babic
mxs_reset_block(struct mxs_register_32 * reg)43*552a848eSStefano Babic int mxs_reset_block(struct mxs_register_32 *reg)
44*552a848eSStefano Babic {
45*552a848eSStefano Babic /* Clear SFTRST */
46*552a848eSStefano Babic writel(MXS_BLOCK_SFTRST, ®->reg_clr);
47*552a848eSStefano Babic
48*552a848eSStefano Babic if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
49*552a848eSStefano Babic return 1;
50*552a848eSStefano Babic
51*552a848eSStefano Babic /* Clear CLKGATE */
52*552a848eSStefano Babic writel(MXS_BLOCK_CLKGATE, ®->reg_clr);
53*552a848eSStefano Babic
54*552a848eSStefano Babic /* Set SFTRST */
55*552a848eSStefano Babic writel(MXS_BLOCK_SFTRST, ®->reg_set);
56*552a848eSStefano Babic
57*552a848eSStefano Babic /* Wait for CLKGATE being set */
58*552a848eSStefano Babic if (mxs_wait_mask_set(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
59*552a848eSStefano Babic return 1;
60*552a848eSStefano Babic
61*552a848eSStefano Babic /* Clear SFTRST */
62*552a848eSStefano Babic writel(MXS_BLOCK_SFTRST, ®->reg_clr);
63*552a848eSStefano Babic
64*552a848eSStefano Babic if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
65*552a848eSStefano Babic return 1;
66*552a848eSStefano Babic
67*552a848eSStefano Babic /* Clear CLKGATE */
68*552a848eSStefano Babic writel(MXS_BLOCK_CLKGATE, ®->reg_clr);
69*552a848eSStefano Babic
70*552a848eSStefano Babic if (mxs_wait_mask_clr(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
71*552a848eSStefano Babic return 1;
72*552a848eSStefano Babic
73*552a848eSStefano Babic return 0;
74*552a848eSStefano Babic }
75