linux/drivers/memory/tegra/tegra20.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
   4 */
   5
   6#include <dt-bindings/memory/tegra20-mc.h>
   7
   8#include "mc.h"
   9
  10static const struct tegra_mc_client tegra20_mc_clients[] = {
  11        {
  12                .id = 0x00,
  13                .name = "display0a",
  14        }, {
  15                .id = 0x01,
  16                .name = "display0ab",
  17        }, {
  18                .id = 0x02,
  19                .name = "display0b",
  20        }, {
  21                .id = 0x03,
  22                .name = "display0bb",
  23        }, {
  24                .id = 0x04,
  25                .name = "display0c",
  26        }, {
  27                .id = 0x05,
  28                .name = "display0cb",
  29        }, {
  30                .id = 0x06,
  31                .name = "display1b",
  32        }, {
  33                .id = 0x07,
  34                .name = "display1bb",
  35        }, {
  36                .id = 0x08,
  37                .name = "eppup",
  38        }, {
  39                .id = 0x09,
  40                .name = "g2pr",
  41        }, {
  42                .id = 0x0a,
  43                .name = "g2sr",
  44        }, {
  45                .id = 0x0b,
  46                .name = "mpeunifbr",
  47        }, {
  48                .id = 0x0c,
  49                .name = "viruv",
  50        }, {
  51                .id = 0x0d,
  52                .name = "avpcarm7r",
  53        }, {
  54                .id = 0x0e,
  55                .name = "displayhc",
  56        }, {
  57                .id = 0x0f,
  58                .name = "displayhcb",
  59        }, {
  60                .id = 0x10,
  61                .name = "fdcdrd",
  62        }, {
  63                .id = 0x11,
  64                .name = "g2dr",
  65        }, {
  66                .id = 0x12,
  67                .name = "host1xdmar",
  68        }, {
  69                .id = 0x13,
  70                .name = "host1xr",
  71        }, {
  72                .id = 0x14,
  73                .name = "idxsrd",
  74        }, {
  75                .id = 0x15,
  76                .name = "mpcorer",
  77        }, {
  78                .id = 0x16,
  79                .name = "mpe_ipred",
  80        }, {
  81                .id = 0x17,
  82                .name = "mpeamemrd",
  83        }, {
  84                .id = 0x18,
  85                .name = "mpecsrd",
  86        }, {
  87                .id = 0x19,
  88                .name = "ppcsahbdmar",
  89        }, {
  90                .id = 0x1a,
  91                .name = "ppcsahbslvr",
  92        }, {
  93                .id = 0x1b,
  94                .name = "texsrd",
  95        }, {
  96                .id = 0x1c,
  97                .name = "vdebsevr",
  98        }, {
  99                .id = 0x1d,
 100                .name = "vdember",
 101        }, {
 102                .id = 0x1e,
 103                .name = "vdemcer",
 104        }, {
 105                .id = 0x1f,
 106                .name = "vdetper",
 107        }, {
 108                .id = 0x20,
 109                .name = "eppu",
 110        }, {
 111                .id = 0x21,
 112                .name = "eppv",
 113        }, {
 114                .id = 0x22,
 115                .name = "eppy",
 116        }, {
 117                .id = 0x23,
 118                .name = "mpeunifbw",
 119        }, {
 120                .id = 0x24,
 121                .name = "viwsb",
 122        }, {
 123                .id = 0x25,
 124                .name = "viwu",
 125        }, {
 126                .id = 0x26,
 127                .name = "viwv",
 128        }, {
 129                .id = 0x27,
 130                .name = "viwy",
 131        }, {
 132                .id = 0x28,
 133                .name = "g2dw",
 134        }, {
 135                .id = 0x29,
 136                .name = "avpcarm7w",
 137        }, {
 138                .id = 0x2a,
 139                .name = "fdcdwr",
 140        }, {
 141                .id = 0x2b,
 142                .name = "host1xw",
 143        }, {
 144                .id = 0x2c,
 145                .name = "ispw",
 146        }, {
 147                .id = 0x2d,
 148                .name = "mpcorew",
 149        }, {
 150                .id = 0x2e,
 151                .name = "mpecswr",
 152        }, {
 153                .id = 0x2f,
 154                .name = "ppcsahbdmaw",
 155        }, {
 156                .id = 0x30,
 157                .name = "ppcsahbslvw",
 158        }, {
 159                .id = 0x31,
 160                .name = "vdebsevw",
 161        }, {
 162                .id = 0x32,
 163                .name = "vdembew",
 164        }, {
 165                .id = 0x33,
 166                .name = "vdetpmw",
 167        },
 168};
 169
 170#define TEGRA20_MC_RESET(_name, _control, _status, _reset, _bit)        \
 171        {                                                               \
 172                .name = #_name,                                         \
 173                .id = TEGRA20_MC_RESET_##_name,                         \
 174                .control = _control,                                    \
 175                .status = _status,                                      \
 176                .reset = _reset,                                        \
 177                .bit = _bit,                                            \
 178        }
 179
 180static const struct tegra_mc_reset tegra20_mc_resets[] = {
 181        TEGRA20_MC_RESET(AVPC,   0x100, 0x140, 0x104,  0),
 182        TEGRA20_MC_RESET(DC,     0x100, 0x144, 0x104,  1),
 183        TEGRA20_MC_RESET(DCB,    0x100, 0x148, 0x104,  2),
 184        TEGRA20_MC_RESET(EPP,    0x100, 0x14c, 0x104,  3),
 185        TEGRA20_MC_RESET(2D,     0x100, 0x150, 0x104,  4),
 186        TEGRA20_MC_RESET(HC,     0x100, 0x154, 0x104,  5),
 187        TEGRA20_MC_RESET(ISP,    0x100, 0x158, 0x104,  6),
 188        TEGRA20_MC_RESET(MPCORE, 0x100, 0x15c, 0x104,  7),
 189        TEGRA20_MC_RESET(MPEA,   0x100, 0x160, 0x104,  8),
 190        TEGRA20_MC_RESET(MPEB,   0x100, 0x164, 0x104,  9),
 191        TEGRA20_MC_RESET(MPEC,   0x100, 0x168, 0x104, 10),
 192        TEGRA20_MC_RESET(3D,     0x100, 0x16c, 0x104, 11),
 193        TEGRA20_MC_RESET(PPCS,   0x100, 0x170, 0x104, 12),
 194        TEGRA20_MC_RESET(VDE,    0x100, 0x174, 0x104, 13),
 195        TEGRA20_MC_RESET(VI,     0x100, 0x178, 0x104, 14),
 196};
 197
 198static int tegra20_mc_hotreset_assert(struct tegra_mc *mc,
 199                                      const struct tegra_mc_reset *rst)
 200{
 201        unsigned long flags;
 202        u32 value;
 203
 204        spin_lock_irqsave(&mc->lock, flags);
 205
 206        value = mc_readl(mc, rst->reset);
 207        mc_writel(mc, value & ~BIT(rst->bit), rst->reset);
 208
 209        spin_unlock_irqrestore(&mc->lock, flags);
 210
 211        return 0;
 212}
 213
 214static int tegra20_mc_hotreset_deassert(struct tegra_mc *mc,
 215                                        const struct tegra_mc_reset *rst)
 216{
 217        unsigned long flags;
 218        u32 value;
 219
 220        spin_lock_irqsave(&mc->lock, flags);
 221
 222        value = mc_readl(mc, rst->reset);
 223        mc_writel(mc, value | BIT(rst->bit), rst->reset);
 224
 225        spin_unlock_irqrestore(&mc->lock, flags);
 226
 227        return 0;
 228}
 229
 230static int tegra20_mc_block_dma(struct tegra_mc *mc,
 231                                const struct tegra_mc_reset *rst)
 232{
 233        unsigned long flags;
 234        u32 value;
 235
 236        spin_lock_irqsave(&mc->lock, flags);
 237
 238        value = mc_readl(mc, rst->control) & ~BIT(rst->bit);
 239        mc_writel(mc, value, rst->control);
 240
 241        spin_unlock_irqrestore(&mc->lock, flags);
 242
 243        return 0;
 244}
 245
 246static bool tegra20_mc_dma_idling(struct tegra_mc *mc,
 247                                  const struct tegra_mc_reset *rst)
 248{
 249        return mc_readl(mc, rst->status) == 0;
 250}
 251
 252static int tegra20_mc_reset_status(struct tegra_mc *mc,
 253                                   const struct tegra_mc_reset *rst)
 254{
 255        return (mc_readl(mc, rst->reset) & BIT(rst->bit)) == 0;
 256}
 257
 258static int tegra20_mc_unblock_dma(struct tegra_mc *mc,
 259                                  const struct tegra_mc_reset *rst)
 260{
 261        unsigned long flags;
 262        u32 value;
 263
 264        spin_lock_irqsave(&mc->lock, flags);
 265
 266        value = mc_readl(mc, rst->control) | BIT(rst->bit);
 267        mc_writel(mc, value, rst->control);
 268
 269        spin_unlock_irqrestore(&mc->lock, flags);
 270
 271        return 0;
 272}
 273
 274static const struct tegra_mc_reset_ops tegra20_mc_reset_ops = {
 275        .hotreset_assert = tegra20_mc_hotreset_assert,
 276        .hotreset_deassert = tegra20_mc_hotreset_deassert,
 277        .block_dma = tegra20_mc_block_dma,
 278        .dma_idling = tegra20_mc_dma_idling,
 279        .unblock_dma = tegra20_mc_unblock_dma,
 280        .reset_status = tegra20_mc_reset_status,
 281};
 282
 283const struct tegra_mc_soc tegra20_mc_soc = {
 284        .clients = tegra20_mc_clients,
 285        .num_clients = ARRAY_SIZE(tegra20_mc_clients),
 286        .num_address_bits = 32,
 287        .client_id_mask = 0x3f,
 288        .intmask = MC_INT_SECURITY_VIOLATION | MC_INT_INVALID_GART_PAGE |
 289                   MC_INT_DECERR_EMEM,
 290        .reset_ops = &tegra20_mc_reset_ops,
 291        .resets = tegra20_mc_resets,
 292        .num_resets = ARRAY_SIZE(tegra20_mc_resets),
 293};
 294