xref: /rk3399_rockchip-uboot/arch/arm/mach-imx/misc.c (revision 39632b4a01210e329333d787d828157dcd2c7328)
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->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->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->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->reg_clr);
53*552a848eSStefano Babic 
54*552a848eSStefano Babic 	/* Set SFTRST */
55*552a848eSStefano Babic 	writel(MXS_BLOCK_SFTRST, &reg->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->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->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