linux/arch/arm/mach-imx/system.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 1999 ARM Limited
   3 * Copyright (C) 2000 Deep Blue Solutions Ltd
   4 * Copyright 2006-2007 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/of.h>
  25#include <linux/of_address.h>
  26
  27#include <asm/system_misc.h>
  28#include <asm/proc-fns.h>
  29#include <asm/mach-types.h>
  30#include <asm/hardware/cache-l2x0.h>
  31
  32#include "common.h"
  33#include "hardware.h"
  34
  35static void __iomem *wdog_base;
  36static struct clk *wdog_clk;
  37
  38/*
  39 * Reset the system. It is called by machine_restart().
  40 */
  41void mxc_restart(enum reboot_mode mode, const char *cmd)
  42{
  43        unsigned int wcr_enable;
  44
  45        if (!wdog_base)
  46                goto reset_fallback;
  47
  48        if (!IS_ERR(wdog_clk))
  49                clk_enable(wdog_clk);
  50
  51        if (cpu_is_mx1())
  52                wcr_enable = (1 << 0);
  53        else
  54                wcr_enable = (1 << 2);
  55
  56        /* Assert SRS signal */
  57        imx_writew(wcr_enable, wdog_base);
  58        /*
  59         * Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be
  60         * written twice), we add another two writes to ensure there must be at
  61         * least two writes happen in the same one 32kHz clock period.  We save
  62         * the target check here, since the writes shouldn't be a huge burden
  63         * for other platforms.
  64         */
  65        imx_writew(wcr_enable, wdog_base);
  66        imx_writew(wcr_enable, wdog_base);
  67
  68        /* wait for reset to assert... */
  69        mdelay(500);
  70
  71        pr_err("%s: Watchdog reset failed to assert reset\n", __func__);
  72
  73        /* delay to allow the serial port to show the message */
  74        mdelay(50);
  75
  76reset_fallback:
  77        /* we'll take a jump through zero as a poor second */
  78        soft_restart(0);
  79}
  80
  81void __init mxc_arch_reset_init(void __iomem *base)
  82{
  83        wdog_base = base;
  84
  85        wdog_clk = clk_get_sys("imx2-wdt.0", NULL);
  86        if (IS_ERR(wdog_clk))
  87                pr_warn("%s: failed to get wdog clock\n", __func__);
  88        else
  89                clk_prepare(wdog_clk);
  90}
  91
  92#ifdef CONFIG_CACHE_L2X0
  93void __init imx_init_l2cache(void)
  94{
  95        void __iomem *l2x0_base;
  96        struct device_node *np;
  97        unsigned int val;
  98
  99        np = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
 100        if (!np)
 101                goto out;
 102
 103        l2x0_base = of_iomap(np, 0);
 104        if (!l2x0_base) {
 105                of_node_put(np);
 106                goto out;
 107        }
 108
 109        if (readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)
 110                goto skip_if_enabled;
 111
 112        /* Configure the L2 PREFETCH and POWER registers */
 113        val = readl_relaxed(l2x0_base + L310_PREFETCH_CTRL);
 114        val |= 0x70800000;
 115        /*
 116         * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
 117         * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2
 118         * But according to ARM PL310 errata: 752271
 119         * ID: 752271: Double linefill feature can cause data corruption
 120         * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2
 121         * Workaround: The only workaround to this erratum is to disable the
 122         * double linefill feature. This is the default behavior.
 123         */
 124        if (cpu_is_imx6q())
 125                val &= ~(1 << 30 | 1 << 23);
 126        writel_relaxed(val, l2x0_base + L310_PREFETCH_CTRL);
 127
 128skip_if_enabled:
 129        iounmap(l2x0_base);
 130        of_node_put(np);
 131
 132out:
 133        l2x0_of_init(0, ~0);
 134}
 135#endif
 136