/*1* Copyright (C) 1999 ARM Limited2* Copyright (C) 2000 Deep Blue Solutions Ltd3* Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.4* Copyright 2008 Juergen Beisert, [email protected]5* Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, [email protected]6*7* This program is free software; you can redistribute it and/or modify8* it under the terms of the GNU General Public License as published by9* the Free Software Foundation; either version 2 of the License, or10* (at your option) any later version.11*12* This program is distributed in the hope that it will be useful,13* but WITHOUT ANY WARRANTY; without even the implied warranty of14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15* GNU General Public License for more details.16*/1718#include <linux/kernel.h>19#include <linux/clk.h>20#include <linux/io.h>21#include <linux/err.h>22#include <linux/delay.h>23#include <linux/init.h>24#include <linux/module.h>2526#include <asm/proc-fns.h>27#include <asm/system.h>2829#include <mach/mxs.h>30#include <mach/common.h>3132#define MX23_CLKCTRL_RESET_OFFSET 0x12033#define MX28_CLKCTRL_RESET_OFFSET 0x1e034#define MXS_CLKCTRL_RESET_CHIP (1 << 1)3536#define MXS_MODULE_CLKGATE (1 << 30)37#define MXS_MODULE_SFTRST (1 << 31)3839static void __iomem *mxs_clkctrl_reset_addr;4041/*42* Reset the system. It is called by machine_restart().43*/44void arch_reset(char mode, const char *cmd)45{46/* reset the chip */47__mxs_setl(MXS_CLKCTRL_RESET_CHIP, mxs_clkctrl_reset_addr);4849pr_err("Failed to assert the chip reset\n");5051/* Delay to allow the serial port to show the message */52mdelay(50);5354/* We'll take a jump through zero as a poor second */55cpu_reset(0);56}5758static int __init mxs_arch_reset_init(void)59{60struct clk *clk;6162mxs_clkctrl_reset_addr = MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR) +63(cpu_is_mx23() ? MX23_CLKCTRL_RESET_OFFSET :64MX28_CLKCTRL_RESET_OFFSET);6566clk = clk_get_sys("rtc", NULL);67if (!IS_ERR(clk))68clk_enable(clk);6970return 0;71}72core_initcall(mxs_arch_reset_init);7374/*75* Clear the bit and poll it cleared. This is usually called with76* a reset address and mask being either SFTRST(bit 31) or CLKGATE77* (bit 30).78*/79static int clear_poll_bit(void __iomem *addr, u32 mask)80{81int timeout = 0x400;8283/* clear the bit */84__mxs_clrl(mask, addr);8586/*87* SFTRST needs 3 GPMI clocks to settle, the reference manual88* recommends to wait 1us.89*/90udelay(1);9192/* poll the bit becoming clear */93while ((__raw_readl(addr) & mask) && --timeout)94/* nothing */;9596return !timeout;97}9899int mxs_reset_block(void __iomem *reset_addr)100{101int ret;102int timeout = 0x400;103104/* clear and poll SFTRST */105ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);106if (unlikely(ret))107goto error;108109/* clear CLKGATE */110__mxs_clrl(MXS_MODULE_CLKGATE, reset_addr);111112/* set SFTRST to reset the block */113__mxs_setl(MXS_MODULE_SFTRST, reset_addr);114udelay(1);115116/* poll CLKGATE becoming set */117while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)118/* nothing */;119if (unlikely(!timeout))120goto error;121122/* clear and poll SFTRST */123ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);124if (unlikely(ret))125goto error;126127/* clear and poll CLKGATE */128ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);129if (unlikely(ret))130goto error;131132return 0;133134error:135pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);136return -ETIMEDOUT;137}138EXPORT_SYMBOL(mxs_reset_block);139140141