linux/drivers/power/reset/at91-reset.c
<<
>>
Prefs
   1/*
   2 * Atmel AT91 SAM9 & SAMA5 SoCs reset code
   3 *
   4 * Copyright (C) 2007 Atmel Corporation.
   5 * Copyright (C) BitBox Ltd 2010
   6 * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcosoft.com>
   7 * Copyright (C) 2014 Free Electrons
   8 *
   9 * This file is licensed under the terms of the GNU General Public
  10 * License version 2.  This program is licensed "as is" without any
  11 * warranty of any kind, whether express or implied.
  12 */
  13
  14#include <linux/clk.h>
  15#include <linux/io.h>
  16#include <linux/module.h>
  17#include <linux/of_address.h>
  18#include <linux/platform_device.h>
  19#include <linux/reboot.h>
  20
  21#include <soc/at91/at91sam9_ddrsdr.h>
  22#include <soc/at91/at91sam9_sdramc.h>
  23
  24#define AT91_RSTC_CR    0x00            /* Reset Controller Control Register */
  25#define AT91_RSTC_PROCRST       BIT(0)          /* Processor Reset */
  26#define AT91_RSTC_PERRST        BIT(2)          /* Peripheral Reset */
  27#define AT91_RSTC_EXTRST        BIT(3)          /* External Reset */
  28#define AT91_RSTC_KEY           (0xa5 << 24)    /* KEY Password */
  29
  30#define AT91_RSTC_SR    0x04            /* Reset Controller Status Register */
  31#define AT91_RSTC_URSTS         BIT(0)          /* User Reset Status */
  32#define AT91_RSTC_RSTTYP        GENMASK(10, 8)  /* Reset Type */
  33#define AT91_RSTC_NRSTL         BIT(16)         /* NRST Pin Level */
  34#define AT91_RSTC_SRCMP         BIT(17)         /* Software Reset Command in Progress */
  35
  36#define AT91_RSTC_MR    0x08            /* Reset Controller Mode Register */
  37#define AT91_RSTC_URSTEN        BIT(0)          /* User Reset Enable */
  38#define AT91_RSTC_URSTASYNC     BIT(2)          /* User Reset Asynchronous Control */
  39#define AT91_RSTC_URSTIEN       BIT(4)          /* User Reset Interrupt Enable */
  40#define AT91_RSTC_ERSTL         GENMASK(11, 8)  /* External Reset Length */
  41
  42enum reset_type {
  43        RESET_TYPE_GENERAL      = 0,
  44        RESET_TYPE_WAKEUP       = 1,
  45        RESET_TYPE_WATCHDOG     = 2,
  46        RESET_TYPE_SOFTWARE     = 3,
  47        RESET_TYPE_USER         = 4,
  48        RESET_TYPE_CPU_FAIL     = 6,
  49        RESET_TYPE_XTAL_FAIL    = 7,
  50        RESET_TYPE_ULP2         = 8,
  51};
  52
  53struct at91_reset {
  54        void __iomem *rstc_base;
  55        void __iomem *ramc_base[2];
  56        struct clk *sclk;
  57        struct notifier_block nb;
  58        u32 args;
  59        u32 ramc_lpr;
  60};
  61
  62/*
  63* unless the SDRAM is cleanly shutdown before we hit the
  64* reset register it can be left driving the data bus and
  65* killing the chance of a subsequent boot from NAND
  66*/
  67static int at91_reset(struct notifier_block *this, unsigned long mode,
  68                      void *cmd)
  69{
  70        struct at91_reset *reset = container_of(this, struct at91_reset, nb);
  71
  72        asm volatile(
  73                /* Align to cache lines */
  74                ".balign 32\n\t"
  75
  76                /* Disable SDRAM0 accesses */
  77                "       tst     %0, #0\n\t"
  78                "       beq     1f\n\t"
  79                "       str     %3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
  80                /* Power down SDRAM0 */
  81                "       str     %4, [%0, %6]\n\t"
  82                /* Disable SDRAM1 accesses */
  83                "1:     tst     %1, #0\n\t"
  84                "       beq     2f\n\t"
  85                "       strne   %3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t"
  86                /* Power down SDRAM1 */
  87                "       strne   %4, [%1, %6]\n\t"
  88                /* Reset CPU */
  89                "2:     str     %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t"
  90
  91                "       b       .\n\t"
  92                :
  93                : "r" (reset->ramc_base[0]),
  94                  "r" (reset->ramc_base[1]),
  95                  "r" (reset->rstc_base),
  96                  "r" (1),
  97                  "r" cpu_to_le32(AT91_DDRSDRC_LPCB_POWER_DOWN),
  98                  "r" (reset->args),
  99                  "r" (reset->ramc_lpr)
 100                : "r4");
 101
 102        return NOTIFY_DONE;
 103}
 104
 105static void __init at91_reset_status(struct platform_device *pdev,
 106                                     void __iomem *base)
 107{
 108        const char *reason;
 109        u32 reg = readl(base + AT91_RSTC_SR);
 110
 111        switch ((reg & AT91_RSTC_RSTTYP) >> 8) {
 112        case RESET_TYPE_GENERAL:
 113                reason = "general reset";
 114                break;
 115        case RESET_TYPE_WAKEUP:
 116                reason = "wakeup";
 117                break;
 118        case RESET_TYPE_WATCHDOG:
 119                reason = "watchdog reset";
 120                break;
 121        case RESET_TYPE_SOFTWARE:
 122                reason = "software reset";
 123                break;
 124        case RESET_TYPE_USER:
 125                reason = "user reset";
 126                break;
 127        case RESET_TYPE_CPU_FAIL:
 128                reason = "CPU clock failure detection";
 129                break;
 130        case RESET_TYPE_XTAL_FAIL:
 131                reason = "32.768 kHz crystal failure detection";
 132                break;
 133        case RESET_TYPE_ULP2:
 134                reason = "ULP2 reset";
 135                break;
 136        default:
 137                reason = "unknown reset";
 138                break;
 139        }
 140
 141        dev_info(&pdev->dev, "Starting after %s\n", reason);
 142}
 143
 144static const struct of_device_id at91_ramc_of_match[] = {
 145        {
 146                .compatible = "atmel,at91sam9260-sdramc",
 147                .data = (void *)AT91_SDRAMC_LPR,
 148        },
 149        {
 150                .compatible = "atmel,at91sam9g45-ddramc",
 151                .data = (void *)AT91_DDRSDRC_LPR,
 152        },
 153        { /* sentinel */ }
 154};
 155
 156static const struct of_device_id at91_reset_of_match[] = {
 157        {
 158                .compatible = "atmel,at91sam9260-rstc",
 159                .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PERRST |
 160                                 AT91_RSTC_PROCRST),
 161        },
 162        {
 163                .compatible = "atmel,at91sam9g45-rstc",
 164                .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PERRST |
 165                                 AT91_RSTC_PROCRST)
 166        },
 167        {
 168                .compatible = "atmel,sama5d3-rstc",
 169                .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PERRST |
 170                                 AT91_RSTC_PROCRST)
 171        },
 172        {
 173                .compatible = "atmel,samx7-rstc",
 174                .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PROCRST)
 175        },
 176        {
 177                .compatible = "microchip,sam9x60-rstc",
 178                .data = (void *)(AT91_RSTC_KEY | AT91_RSTC_PROCRST)
 179        },
 180        { /* sentinel */ }
 181};
 182MODULE_DEVICE_TABLE(of, at91_reset_of_match);
 183
 184static int __init at91_reset_probe(struct platform_device *pdev)
 185{
 186        const struct of_device_id *match;
 187        struct at91_reset *reset;
 188        struct device_node *np;
 189        int ret, idx = 0;
 190
 191        reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
 192        if (!reset)
 193                return -ENOMEM;
 194
 195        reset->rstc_base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL);
 196        if (IS_ERR(reset->rstc_base)) {
 197                dev_err(&pdev->dev, "Could not map reset controller address\n");
 198                return -ENODEV;
 199        }
 200
 201        if (!of_device_is_compatible(pdev->dev.of_node, "atmel,sama5d3-rstc")) {
 202                /* we need to shutdown the ddr controller, so get ramc base */
 203                for_each_matching_node_and_match(np, at91_ramc_of_match, &match) {
 204                        reset->ramc_lpr = (u32)match->data;
 205                        reset->ramc_base[idx] = devm_of_iomap(&pdev->dev, np, 0, NULL);
 206                        if (IS_ERR(reset->ramc_base[idx])) {
 207                                dev_err(&pdev->dev, "Could not map ram controller address\n");
 208                                of_node_put(np);
 209                                return -ENODEV;
 210                        }
 211                        idx++;
 212                }
 213        }
 214
 215        match = of_match_node(at91_reset_of_match, pdev->dev.of_node);
 216        reset->nb.notifier_call = at91_reset;
 217        reset->nb.priority = 192;
 218        reset->args = (u32)match->data;
 219
 220        reset->sclk = devm_clk_get(&pdev->dev, NULL);
 221        if (IS_ERR(reset->sclk))
 222                return PTR_ERR(reset->sclk);
 223
 224        ret = clk_prepare_enable(reset->sclk);
 225        if (ret) {
 226                dev_err(&pdev->dev, "Could not enable slow clock\n");
 227                return ret;
 228        }
 229
 230        platform_set_drvdata(pdev, reset);
 231
 232        if (of_device_is_compatible(pdev->dev.of_node, "microchip,sam9x60-rstc")) {
 233                u32 val = readl(reset->rstc_base + AT91_RSTC_MR);
 234
 235                writel(AT91_RSTC_KEY | AT91_RSTC_URSTASYNC | val,
 236                       reset->rstc_base + AT91_RSTC_MR);
 237        }
 238
 239        ret = register_restart_handler(&reset->nb);
 240        if (ret) {
 241                clk_disable_unprepare(reset->sclk);
 242                return ret;
 243        }
 244
 245        at91_reset_status(pdev, reset->rstc_base);
 246
 247        return 0;
 248}
 249
 250static int __exit at91_reset_remove(struct platform_device *pdev)
 251{
 252        struct at91_reset *reset = platform_get_drvdata(pdev);
 253
 254        unregister_restart_handler(&reset->nb);
 255        clk_disable_unprepare(reset->sclk);
 256
 257        return 0;
 258}
 259
 260static struct platform_driver at91_reset_driver = {
 261        .remove = __exit_p(at91_reset_remove),
 262        .driver = {
 263                .name = "at91-reset",
 264                .of_match_table = at91_reset_of_match,
 265        },
 266};
 267module_platform_driver_probe(at91_reset_driver, at91_reset_probe);
 268
 269MODULE_AUTHOR("Atmel Corporation");
 270MODULE_DESCRIPTION("Reset driver for Atmel SoCs");
 271MODULE_LICENSE("GPL v2");
 272