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