linux/arch/arm/mach-mxs/system.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 1999 ARM Limited
   3 * Copyright (C) 2000 Deep Blue Solutions Ltd
   4 * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
   5 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
   6 * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok@emcraft.com
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 */
  18
  19#include <linux/kernel.h>
  20#include <linux/clk.h>
  21#include <linux/io.h>
  22#include <linux/err.h>
  23#include <linux/delay.h>
  24#include <linux/init.h>
  25#include <linux/module.h>
  26
  27#include <asm/proc-fns.h>
  28#include <asm/system.h>
  29
  30#include <mach/mxs.h>
  31#include <mach/common.h>
  32
  33#define MX23_CLKCTRL_RESET_OFFSET       0x120
  34#define MX28_CLKCTRL_RESET_OFFSET       0x1e0
  35#define MXS_CLKCTRL_RESET_CHIP          (1 << 1)
  36
  37#define MXS_MODULE_CLKGATE              (1 << 30)
  38#define MXS_MODULE_SFTRST               (1 << 31)
  39
  40static void __iomem *mxs_clkctrl_reset_addr;
  41
  42/*
  43 * Reset the system. It is called by machine_restart().
  44 */
  45void arch_reset(char mode, const char *cmd)
  46{
  47        /* reset the chip */
  48        __mxs_setl(MXS_CLKCTRL_RESET_CHIP, mxs_clkctrl_reset_addr);
  49
  50        pr_err("Failed to assert the chip reset\n");
  51
  52        /* Delay to allow the serial port to show the message */
  53        mdelay(50);
  54
  55        /* We'll take a jump through zero as a poor second */
  56        cpu_reset(0);
  57}
  58
  59static int __init mxs_arch_reset_init(void)
  60{
  61        struct clk *clk;
  62
  63        mxs_clkctrl_reset_addr = MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR) +
  64                                (cpu_is_mx23() ? MX23_CLKCTRL_RESET_OFFSET :
  65                                                 MX28_CLKCTRL_RESET_OFFSET);
  66
  67        clk = clk_get_sys("rtc", NULL);
  68        if (!IS_ERR(clk))
  69                clk_enable(clk);
  70
  71        return 0;
  72}
  73core_initcall(mxs_arch_reset_init);
  74
  75/*
  76 * Clear the bit and poll it cleared.  This is usually called with
  77 * a reset address and mask being either SFTRST(bit 31) or CLKGATE
  78 * (bit 30).
  79 */
  80static int clear_poll_bit(void __iomem *addr, u32 mask)
  81{
  82        int timeout = 0x400;
  83
  84        /* clear the bit */
  85        __mxs_clrl(mask, addr);
  86
  87        /*
  88         * SFTRST needs 3 GPMI clocks to settle, the reference manual
  89         * recommends to wait 1us.
  90         */
  91        udelay(1);
  92
  93        /* poll the bit becoming clear */
  94        while ((__raw_readl(addr) & mask) && --timeout)
  95                /* nothing */;
  96
  97        return !timeout;
  98}
  99
 100int mxs_reset_block(void __iomem *reset_addr)
 101{
 102        int ret;
 103        int timeout = 0x400;
 104
 105        /* clear and poll SFTRST */
 106        ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
 107        if (unlikely(ret))
 108                goto error;
 109
 110        /* clear CLKGATE */
 111        __mxs_clrl(MXS_MODULE_CLKGATE, reset_addr);
 112
 113        /* set SFTRST to reset the block */
 114        __mxs_setl(MXS_MODULE_SFTRST, reset_addr);
 115        udelay(1);
 116
 117        /* poll CLKGATE becoming set */
 118        while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
 119                /* nothing */;
 120        if (unlikely(!timeout))
 121                goto error;
 122
 123        /* clear and poll SFTRST */
 124        ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
 125        if (unlikely(ret))
 126                goto error;
 127
 128        /* clear and poll CLKGATE */
 129        ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
 130        if (unlikely(ret))
 131                goto error;
 132
 133        return 0;
 134
 135error:
 136        pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
 137        return -ETIMEDOUT;
 138}
 139EXPORT_SYMBOL(mxs_reset_block);
 140