Skip to content
Snippets Groups Projects
misc.c 2.01 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * 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->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->reg) & mask) == 0)
    			break;
    		udelay(1);
    	}
    
    	return !timeout;
    }
    
    int mxs_reset_block(struct mxs_register_32 *reg)
    {
    	/* Clear SFTRST */
    	writel(MXS_BLOCK_SFTRST, &reg->reg_clr);
    
    	if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
    		return 1;
    
    	/* Clear CLKGATE */
    	writel(MXS_BLOCK_CLKGATE, &reg->reg_clr);
    
    	/* Set SFTRST */
    	writel(MXS_BLOCK_SFTRST, &reg->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->reg_clr);
    
    	if (mxs_wait_mask_clr(reg, MXS_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
    		return 1;
    
    	/* Clear CLKGATE */
    	writel(MXS_BLOCK_CLKGATE, &reg->reg_clr);
    
    	if (mxs_wait_mask_clr(reg, MXS_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
    		return 1;
    
    	return 0;
    }