linux/arch/mips/bcm63xx/reset.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
   7 */
   8
   9#include <linux/init.h>
  10#include <linux/export.h>
  11#include <linux/mutex.h>
  12#include <linux/err.h>
  13#include <linux/clk.h>
  14#include <linux/delay.h>
  15#include <bcm63xx_cpu.h>
  16#include <bcm63xx_io.h>
  17#include <bcm63xx_regs.h>
  18#include <bcm63xx_reset.h>
  19
  20#define __GEN_RESET_BITS_TABLE(__cpu)                                   \
  21        [BCM63XX_RESET_SPI]             = BCM## __cpu ##_RESET_SPI,     \
  22        [BCM63XX_RESET_ENET]            = BCM## __cpu ##_RESET_ENET,    \
  23        [BCM63XX_RESET_USBH]            = BCM## __cpu ##_RESET_USBH,    \
  24        [BCM63XX_RESET_USBD]            = BCM## __cpu ##_RESET_USBD,    \
  25        [BCM63XX_RESET_DSL]             = BCM## __cpu ##_RESET_DSL,     \
  26        [BCM63XX_RESET_SAR]             = BCM## __cpu ##_RESET_SAR,     \
  27        [BCM63XX_RESET_EPHY]            = BCM## __cpu ##_RESET_EPHY,    \
  28        [BCM63XX_RESET_ENETSW]          = BCM## __cpu ##_RESET_ENETSW,  \
  29        [BCM63XX_RESET_PCM]             = BCM## __cpu ##_RESET_PCM,     \
  30        [BCM63XX_RESET_MPI]             = BCM## __cpu ##_RESET_MPI,     \
  31        [BCM63XX_RESET_PCIE]            = BCM## __cpu ##_RESET_PCIE,    \
  32        [BCM63XX_RESET_PCIE_EXT]        = BCM## __cpu ##_RESET_PCIE_EXT,
  33
  34#define BCM3368_RESET_SPI       SOFTRESET_3368_SPI_MASK
  35#define BCM3368_RESET_ENET      SOFTRESET_3368_ENET_MASK
  36#define BCM3368_RESET_USBH      0
  37#define BCM3368_RESET_USBD      SOFTRESET_3368_USBS_MASK
  38#define BCM3368_RESET_DSL       0
  39#define BCM3368_RESET_SAR       0
  40#define BCM3368_RESET_EPHY      SOFTRESET_3368_EPHY_MASK
  41#define BCM3368_RESET_ENETSW    0
  42#define BCM3368_RESET_PCM       SOFTRESET_3368_PCM_MASK
  43#define BCM3368_RESET_MPI       SOFTRESET_3368_MPI_MASK
  44#define BCM3368_RESET_PCIE      0
  45#define BCM3368_RESET_PCIE_EXT  0
  46
  47#define BCM6328_RESET_SPI       SOFTRESET_6328_SPI_MASK
  48#define BCM6328_RESET_ENET      0
  49#define BCM6328_RESET_USBH      SOFTRESET_6328_USBH_MASK
  50#define BCM6328_RESET_USBD      SOFTRESET_6328_USBS_MASK
  51#define BCM6328_RESET_DSL       0
  52#define BCM6328_RESET_SAR       SOFTRESET_6328_SAR_MASK
  53#define BCM6328_RESET_EPHY      SOFTRESET_6328_EPHY_MASK
  54#define BCM6328_RESET_ENETSW    SOFTRESET_6328_ENETSW_MASK
  55#define BCM6328_RESET_PCM       SOFTRESET_6328_PCM_MASK
  56#define BCM6328_RESET_MPI       0
  57#define BCM6328_RESET_PCIE      \
  58                                (SOFTRESET_6328_PCIE_MASK |             \
  59                                 SOFTRESET_6328_PCIE_CORE_MASK |        \
  60                                 SOFTRESET_6328_PCIE_HARD_MASK)
  61#define BCM6328_RESET_PCIE_EXT  SOFTRESET_6328_PCIE_EXT_MASK
  62
  63#define BCM6338_RESET_SPI       SOFTRESET_6338_SPI_MASK
  64#define BCM6338_RESET_ENET      SOFTRESET_6338_ENET_MASK
  65#define BCM6338_RESET_USBH      SOFTRESET_6338_USBH_MASK
  66#define BCM6338_RESET_USBD      SOFTRESET_6338_USBS_MASK
  67#define BCM6338_RESET_DSL       SOFTRESET_6338_ADSL_MASK
  68#define BCM6338_RESET_SAR       SOFTRESET_6338_SAR_MASK
  69#define BCM6338_RESET_EPHY      0
  70#define BCM6338_RESET_ENETSW    0
  71#define BCM6338_RESET_PCM       0
  72#define BCM6338_RESET_MPI       0
  73#define BCM6338_RESET_PCIE      0
  74#define BCM6338_RESET_PCIE_EXT  0
  75
  76#define BCM6348_RESET_SPI       SOFTRESET_6348_SPI_MASK
  77#define BCM6348_RESET_ENET      SOFTRESET_6348_ENET_MASK
  78#define BCM6348_RESET_USBH      SOFTRESET_6348_USBH_MASK
  79#define BCM6348_RESET_USBD      SOFTRESET_6348_USBS_MASK
  80#define BCM6348_RESET_DSL       SOFTRESET_6348_ADSL_MASK
  81#define BCM6348_RESET_SAR       SOFTRESET_6348_SAR_MASK
  82#define BCM6348_RESET_EPHY      0
  83#define BCM6348_RESET_ENETSW    0
  84#define BCM6348_RESET_PCM       0
  85#define BCM6348_RESET_MPI       0
  86#define BCM6348_RESET_PCIE      0
  87#define BCM6348_RESET_PCIE_EXT  0
  88
  89#define BCM6358_RESET_SPI       SOFTRESET_6358_SPI_MASK
  90#define BCM6358_RESET_ENET      SOFTRESET_6358_ENET_MASK
  91#define BCM6358_RESET_USBH      SOFTRESET_6358_USBH_MASK
  92#define BCM6358_RESET_USBD      0
  93#define BCM6358_RESET_DSL       SOFTRESET_6358_ADSL_MASK
  94#define BCM6358_RESET_SAR       SOFTRESET_6358_SAR_MASK
  95#define BCM6358_RESET_EPHY      SOFTRESET_6358_EPHY_MASK
  96#define BCM6358_RESET_ENETSW    0
  97#define BCM6358_RESET_PCM       SOFTRESET_6358_PCM_MASK
  98#define BCM6358_RESET_MPI       SOFTRESET_6358_MPI_MASK
  99#define BCM6358_RESET_PCIE      0
 100#define BCM6358_RESET_PCIE_EXT  0
 101
 102#define BCM6362_RESET_SPI       SOFTRESET_6362_SPI_MASK
 103#define BCM6362_RESET_ENET      0
 104#define BCM6362_RESET_USBH      SOFTRESET_6362_USBH_MASK
 105#define BCM6362_RESET_USBD      SOFTRESET_6362_USBS_MASK
 106#define BCM6362_RESET_DSL       0
 107#define BCM6362_RESET_SAR       SOFTRESET_6362_SAR_MASK
 108#define BCM6362_RESET_EPHY      SOFTRESET_6362_EPHY_MASK
 109#define BCM6362_RESET_ENETSW    SOFTRESET_6362_ENETSW_MASK
 110#define BCM6362_RESET_PCM       SOFTRESET_6362_PCM_MASK
 111#define BCM6362_RESET_MPI       0
 112#define BCM6362_RESET_PCIE      (SOFTRESET_6362_PCIE_MASK | \
 113                                 SOFTRESET_6362_PCIE_CORE_MASK)
 114#define BCM6362_RESET_PCIE_EXT  SOFTRESET_6362_PCIE_EXT_MASK
 115
 116#define BCM6368_RESET_SPI       SOFTRESET_6368_SPI_MASK
 117#define BCM6368_RESET_ENET      0
 118#define BCM6368_RESET_USBH      SOFTRESET_6368_USBH_MASK
 119#define BCM6368_RESET_USBD      SOFTRESET_6368_USBS_MASK
 120#define BCM6368_RESET_DSL       0
 121#define BCM6368_RESET_SAR       SOFTRESET_6368_SAR_MASK
 122#define BCM6368_RESET_EPHY      SOFTRESET_6368_EPHY_MASK
 123#define BCM6368_RESET_ENETSW    SOFTRESET_6368_ENETSW_MASK
 124#define BCM6368_RESET_PCM       SOFTRESET_6368_PCM_MASK
 125#define BCM6368_RESET_MPI       SOFTRESET_6368_MPI_MASK
 126#define BCM6368_RESET_PCIE      0
 127#define BCM6368_RESET_PCIE_EXT  0
 128
 129/*
 130 * core reset bits
 131 */
 132static const u32 bcm3368_reset_bits[] = {
 133        __GEN_RESET_BITS_TABLE(3368)
 134};
 135
 136static const u32 bcm6328_reset_bits[] = {
 137        __GEN_RESET_BITS_TABLE(6328)
 138};
 139
 140static const u32 bcm6338_reset_bits[] = {
 141        __GEN_RESET_BITS_TABLE(6338)
 142};
 143
 144static const u32 bcm6348_reset_bits[] = {
 145        __GEN_RESET_BITS_TABLE(6348)
 146};
 147
 148static const u32 bcm6358_reset_bits[] = {
 149        __GEN_RESET_BITS_TABLE(6358)
 150};
 151
 152static const u32 bcm6362_reset_bits[] = {
 153        __GEN_RESET_BITS_TABLE(6362)
 154};
 155
 156static const u32 bcm6368_reset_bits[] = {
 157        __GEN_RESET_BITS_TABLE(6368)
 158};
 159
 160const u32 *bcm63xx_reset_bits;
 161static int reset_reg;
 162
 163static int __init bcm63xx_reset_bits_init(void)
 164{
 165        if (BCMCPU_IS_3368()) {
 166                reset_reg = PERF_SOFTRESET_6358_REG;
 167                bcm63xx_reset_bits = bcm3368_reset_bits;
 168        } else if (BCMCPU_IS_6328()) {
 169                reset_reg = PERF_SOFTRESET_6328_REG;
 170                bcm63xx_reset_bits = bcm6328_reset_bits;
 171        } else if (BCMCPU_IS_6338()) {
 172                reset_reg = PERF_SOFTRESET_REG;
 173                bcm63xx_reset_bits = bcm6338_reset_bits;
 174        } else if (BCMCPU_IS_6348()) {
 175                reset_reg = PERF_SOFTRESET_REG;
 176                bcm63xx_reset_bits = bcm6348_reset_bits;
 177        } else if (BCMCPU_IS_6358()) {
 178                reset_reg = PERF_SOFTRESET_6358_REG;
 179                bcm63xx_reset_bits = bcm6358_reset_bits;
 180        } else if (BCMCPU_IS_6362()) {
 181                reset_reg = PERF_SOFTRESET_6362_REG;
 182                bcm63xx_reset_bits = bcm6362_reset_bits;
 183        } else if (BCMCPU_IS_6368()) {
 184                reset_reg = PERF_SOFTRESET_6368_REG;
 185                bcm63xx_reset_bits = bcm6368_reset_bits;
 186        }
 187
 188        return 0;
 189}
 190
 191static DEFINE_SPINLOCK(reset_mutex);
 192
 193static void __bcm63xx_core_set_reset(u32 mask, int enable)
 194{
 195        unsigned long flags;
 196        u32 val;
 197
 198        if (!mask)
 199                return;
 200
 201        spin_lock_irqsave(&reset_mutex, flags);
 202        val = bcm_perf_readl(reset_reg);
 203
 204        if (enable)
 205                val &= ~mask;
 206        else
 207                val |= mask;
 208
 209        bcm_perf_writel(val, reset_reg);
 210        spin_unlock_irqrestore(&reset_mutex, flags);
 211}
 212
 213void bcm63xx_core_set_reset(enum bcm63xx_core_reset core, int reset)
 214{
 215        __bcm63xx_core_set_reset(bcm63xx_reset_bits[core], reset);
 216}
 217EXPORT_SYMBOL(bcm63xx_core_set_reset);
 218
 219postcore_initcall(bcm63xx_reset_bits_init);
 220