diff options
Diffstat (limited to 'arch/arm/imx-common')
-rw-r--r-- | arch/arm/imx-common/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/imx-common/misc.c | 84 |
2 files changed, 87 insertions, 0 deletions
diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile index 44b6822805..9309439420 100644 --- a/arch/arm/imx-common/Makefile +++ b/arch/arm/imx-common/Makefile @@ -31,6 +31,9 @@ ifeq ($(SOC),$(filter $(SOC),mx5 mx6)) COBJS-y = iomux-v3.o timer.o cpu.o speed.o COBJS-$(CONFIG_I2C_MXC) += i2c-mxv7.o endif +ifeq ($(SOC),$(filter $(SOC),mx6 mxs)) +COBJS-y += misc.o +endif COBJS-$(CONFIG_CMD_BMODE) += cmd_bmode.o COBJS-$(CONFIG_CMD_HDMIDETECT) += cmd_hdmidet.o COBJS := $(sort $(COBJS-y)) diff --git a/arch/arm/imx-common/misc.c b/arch/arm/imx-common/misc.c new file mode 100644 index 0000000000..220785ca9e --- /dev/null +++ b/arch/arm/imx-common/misc.c @@ -0,0 +1,84 @@ +/* + * Copyright 2013 Stefan Roese <sr@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/imx-common/regs-common.h> + +/* 1 second delay should be plenty of time for block reset. */ +#define RESET_MAX_TIMEOUT 1000000 + +#define MXS_BLOCK_SFTRST (1 << 31) +#define MXS_BLOCK_CLKGATE (1 << 30) + +int mxs_wait_mask_set(struct mxs_register_32 *reg, uint32_t mask, unsigned + int timeout) +{ + while (--timeout) { + if ((readl(®->reg) & mask) == mask) + break; + udelay(1); + } + + return !timeout; +} + +int mxs_wait_mask_clr(struct mxs_register_32 *reg, uint32_t mask, unsigned + int timeout) +{ + while (--timeout) { + if ((readl(®->reg) & mask) == 0) + break; + udelay(1); + } + + return !timeout; +} + +int mxs_reset_block(struct mxs_register_32 *reg) +{ + /* Clear SFTRST */ + writel(MXS_BLOCK_SFTRST, ®->reg_clr); + + if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) + return 1; + + /* Clear CLKGATE */ + writel(MXS_BLOCK_CLKGATE, ®->reg_clr); + + /* Set SFTRST */ + writel(MXS_BLOCK_SFTRST, ®->reg_set); + + /* Wait for CLKGATE being set */ + if (mxs_wait_mask_set(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) + return 1; + + /* Clear SFTRST */ + writel(MXS_BLOCK_SFTRST, ®->reg_clr); + + if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) + return 1; + + /* Clear CLKGATE */ + writel(MXS_BLOCK_CLKGATE, ®->reg_clr); + + if (mxs_wait_mask_clr(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) + return 1; + + return 0; +} |