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