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