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        __raw_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        __raw_writew(wcr_enable, wdog_base);
  66        __raw_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
  92void __init mxc_arch_reset_init_dt(void)
  93{
  94        struct device_node *np;
  95
  96        np = of_find_compatible_node(NULL, NULL, "fsl,imx21-wdt");
  97        wdog_base = of_iomap(np, 0);
  98        WARN_ON(!wdog_base);
  99
 100        wdog_clk = of_clk_get(np, 0);
 101        if (IS_ERR(wdog_clk))
 102                pr_warn("%s: failed to get wdog clock\n", __func__);
 103        else
 104                clk_prepare(wdog_clk);
 105}
 106
 107#ifdef CONFIG_CACHE_L2X0
 108void __init imx_init_l2cache(void)
 109{
 110        void __iomem *l2x0_base;
 111        struct device_node *np;
 112        unsigned int val;
 113
 114        np = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
 115        if (!np)
 116                goto out;
 117
 118        l2x0_base = of_iomap(np, 0);
 119        if (!l2x0_base) {
 120                of_node_put(np);
 121                goto out;
 122        }
 123
 124        /* Configure the L2 PREFETCH and POWER registers */
 125        val = readl_relaxed(l2x0_base + L310_PREFETCH_CTRL);
 126        val |= 0x70800000;
 127        /*
 128         * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
 129         * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2
 130         * But according to ARM PL310 errata: 752271
 131         * ID: 752271: Double linefill feature can cause data corruption
 132         * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2
 133         * Workaround: The only workaround to this erratum is to disable the
 134         * double linefill feature. This is the default behavior.
 135         */
 136        if (cpu_is_imx6q())
 137                val &= ~(1 << 30 | 1 << 23);
 138        writel_relaxed(val, l2x0_base + L310_PREFETCH_CTRL);
 139
 140        iounmap(l2x0_base);
 141        of_node_put(np);
 142
 143out:
 144        l2x0_of_init(0, ~0);
 145}
 146#endif
 147