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