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 10 static 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 180 static 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 198 static 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 214 static 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 230 static 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 246 static 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 252 static 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 258 static 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 274 static 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 283 const 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