xref: /openbmc/linux/drivers/memory/tegra/tegra186.c (revision 045f77ba)
1 /*
2  * Copyright (C) 2017 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 
9 #include <linux/io.h>
10 #include <linux/module.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/platform_device.h>
13 
14 #include <dt-bindings/memory/tegra186-mc.h>
15 
16 struct tegra_mc {
17 	struct device *dev;
18 	void __iomem *regs;
19 };
20 
21 struct tegra_mc_client {
22 	const char *name;
23 	unsigned int sid;
24 	struct {
25 		unsigned int override;
26 		unsigned int security;
27 	} regs;
28 };
29 
30 static const struct tegra_mc_client tegra186_mc_clients[] = {
31 	{
32 		.name = "ptcr",
33 		.sid = TEGRA186_SID_PASSTHROUGH,
34 		.regs = {
35 			.override = 0x000,
36 			.security = 0x004,
37 		},
38 	}, {
39 		.name = "afir",
40 		.sid = TEGRA186_SID_AFI,
41 		.regs = {
42 			.override = 0x070,
43 			.security = 0x074,
44 		},
45 	}, {
46 		.name = "hdar",
47 		.sid = TEGRA186_SID_HDA,
48 		.regs = {
49 			.override = 0x0a8,
50 			.security = 0x0ac,
51 		},
52 	}, {
53 		.name = "host1xdmar",
54 		.sid = TEGRA186_SID_HOST1X,
55 		.regs = {
56 			.override = 0x0b0,
57 			.security = 0x0b4,
58 		},
59 	}, {
60 		.name = "nvencsrd",
61 		.sid = TEGRA186_SID_NVENC,
62 		.regs = {
63 			.override = 0x0e0,
64 			.security = 0x0e4,
65 		},
66 	}, {
67 		.name = "satar",
68 		.sid = TEGRA186_SID_SATA,
69 		.regs = {
70 			.override = 0x0f8,
71 			.security = 0x0fc,
72 		},
73 	}, {
74 		.name = "mpcorer",
75 		.sid = TEGRA186_SID_PASSTHROUGH,
76 		.regs = {
77 			.override = 0x138,
78 			.security = 0x13c,
79 		},
80 	}, {
81 		.name = "nvencswr",
82 		.sid = TEGRA186_SID_NVENC,
83 		.regs = {
84 			.override = 0x158,
85 			.security = 0x15c,
86 		},
87 	}, {
88 		.name = "afiw",
89 		.sid = TEGRA186_SID_AFI,
90 		.regs = {
91 			.override = 0x188,
92 			.security = 0x18c,
93 		},
94 	}, {
95 		.name = "hdaw",
96 		.sid = TEGRA186_SID_HDA,
97 		.regs = {
98 			.override = 0x1a8,
99 			.security = 0x1ac,
100 		},
101 	}, {
102 		.name = "mpcorew",
103 		.sid = TEGRA186_SID_PASSTHROUGH,
104 		.regs = {
105 			.override = 0x1c8,
106 			.security = 0x1cc,
107 		},
108 	}, {
109 		.name = "sataw",
110 		.sid = TEGRA186_SID_SATA,
111 		.regs = {
112 			.override = 0x1e8,
113 			.security = 0x1ec,
114 		},
115 	}, {
116 		.name = "ispra",
117 		.sid = TEGRA186_SID_ISP,
118 		.regs = {
119 			.override = 0x220,
120 			.security = 0x224,
121 		},
122 	}, {
123 		.name = "ispwa",
124 		.sid = TEGRA186_SID_ISP,
125 		.regs = {
126 			.override = 0x230,
127 			.security = 0x234,
128 		},
129 	}, {
130 		.name = "ispwb",
131 		.sid = TEGRA186_SID_ISP,
132 		.regs = {
133 			.override = 0x238,
134 			.security = 0x23c,
135 		},
136 	}, {
137 		.name = "xusb_hostr",
138 		.sid = TEGRA186_SID_XUSB_HOST,
139 		.regs = {
140 			.override = 0x250,
141 			.security = 0x254,
142 		},
143 	}, {
144 		.name = "xusb_hostw",
145 		.sid = TEGRA186_SID_XUSB_HOST,
146 		.regs = {
147 			.override = 0x258,
148 			.security = 0x25c,
149 		},
150 	}, {
151 		.name = "xusb_devr",
152 		.sid = TEGRA186_SID_XUSB_DEV,
153 		.regs = {
154 			.override = 0x260,
155 			.security = 0x264,
156 		},
157 	}, {
158 		.name = "xusb_devw",
159 		.sid = TEGRA186_SID_XUSB_DEV,
160 		.regs = {
161 			.override = 0x268,
162 			.security = 0x26c,
163 		},
164 	}, {
165 		.name = "tsecsrd",
166 		.sid = TEGRA186_SID_TSEC,
167 		.regs = {
168 			.override = 0x2a0,
169 			.security = 0x2a4,
170 		},
171 	}, {
172 		.name = "tsecswr",
173 		.sid = TEGRA186_SID_TSEC,
174 		.regs = {
175 			.override = 0x2a8,
176 			.security = 0x2ac,
177 		},
178 	}, {
179 		.name = "gpusrd",
180 		.sid = TEGRA186_SID_GPU,
181 		.regs = {
182 			.override = 0x2c0,
183 			.security = 0x2c4,
184 		},
185 	}, {
186 		.name = "gpuswr",
187 		.sid = TEGRA186_SID_GPU,
188 		.regs = {
189 			.override = 0x2c8,
190 			.security = 0x2cc,
191 		},
192 	}, {
193 		.name = "sdmmcra",
194 		.sid = TEGRA186_SID_SDMMC1,
195 		.regs = {
196 			.override = 0x300,
197 			.security = 0x304,
198 		},
199 	}, {
200 		.name = "sdmmcraa",
201 		.sid = TEGRA186_SID_SDMMC2,
202 		.regs = {
203 			.override = 0x308,
204 			.security = 0x30c,
205 		},
206 	}, {
207 		.name = "sdmmcr",
208 		.sid = TEGRA186_SID_SDMMC3,
209 		.regs = {
210 			.override = 0x310,
211 			.security = 0x314,
212 		},
213 	}, {
214 		.name = "sdmmcrab",
215 		.sid = TEGRA186_SID_SDMMC4,
216 		.regs = {
217 			.override = 0x318,
218 			.security = 0x31c,
219 		},
220 	}, {
221 		.name = "sdmmcwa",
222 		.sid = TEGRA186_SID_SDMMC1,
223 		.regs = {
224 			.override = 0x320,
225 			.security = 0x324,
226 		},
227 	}, {
228 		.name = "sdmmcwaa",
229 		.sid = TEGRA186_SID_SDMMC2,
230 		.regs = {
231 			.override = 0x328,
232 			.security = 0x32c,
233 		},
234 	}, {
235 		.name = "sdmmcw",
236 		.sid = TEGRA186_SID_SDMMC3,
237 		.regs = {
238 			.override = 0x330,
239 			.security = 0x334,
240 		},
241 	}, {
242 		.name = "sdmmcwab",
243 		.sid = TEGRA186_SID_SDMMC4,
244 		.regs = {
245 			.override = 0x338,
246 			.security = 0x33c,
247 		},
248 	}, {
249 		.name = "vicsrd",
250 		.sid = TEGRA186_SID_VIC,
251 		.regs = {
252 			.override = 0x360,
253 			.security = 0x364,
254 		},
255 	}, {
256 		.name = "vicswr",
257 		.sid = TEGRA186_SID_VIC,
258 		.regs = {
259 			.override = 0x368,
260 			.security = 0x36c,
261 		},
262 	}, {
263 		.name = "viw",
264 		.sid = TEGRA186_SID_VI,
265 		.regs = {
266 			.override = 0x390,
267 			.security = 0x394,
268 		},
269 	}, {
270 		.name = "nvdecsrd",
271 		.sid = TEGRA186_SID_NVDEC,
272 		.regs = {
273 			.override = 0x3c0,
274 			.security = 0x3c4,
275 		},
276 	}, {
277 		.name = "nvdecswr",
278 		.sid = TEGRA186_SID_NVDEC,
279 		.regs = {
280 			.override = 0x3c8,
281 			.security = 0x3cc,
282 		},
283 	}, {
284 		.name = "aper",
285 		.sid = TEGRA186_SID_APE,
286 		.regs = {
287 			.override = 0x3d0,
288 			.security = 0x3d4,
289 		},
290 	}, {
291 		.name = "apew",
292 		.sid = TEGRA186_SID_APE,
293 		.regs = {
294 			.override = 0x3d8,
295 			.security = 0x3dc,
296 		},
297 	}, {
298 		.name = "nvjpgsrd",
299 		.sid = TEGRA186_SID_NVJPG,
300 		.regs = {
301 			.override = 0x3f0,
302 			.security = 0x3f4,
303 		},
304 	}, {
305 		.name = "nvjpgswr",
306 		.sid = TEGRA186_SID_NVJPG,
307 		.regs = {
308 			.override = 0x3f8,
309 			.security = 0x3fc,
310 		},
311 	}, {
312 		.name = "sesrd",
313 		.sid = TEGRA186_SID_SE,
314 		.regs = {
315 			.override = 0x400,
316 			.security = 0x404,
317 		},
318 	}, {
319 		.name = "seswr",
320 		.sid = TEGRA186_SID_SE,
321 		.regs = {
322 			.override = 0x408,
323 			.security = 0x40c,
324 		},
325 	}, {
326 		.name = "etrr",
327 		.sid = TEGRA186_SID_ETR,
328 		.regs = {
329 			.override = 0x420,
330 			.security = 0x424,
331 		},
332 	}, {
333 		.name = "etrw",
334 		.sid = TEGRA186_SID_ETR,
335 		.regs = {
336 			.override = 0x428,
337 			.security = 0x42c,
338 		},
339 	}, {
340 		.name = "tsecsrdb",
341 		.sid = TEGRA186_SID_TSECB,
342 		.regs = {
343 			.override = 0x430,
344 			.security = 0x434,
345 		},
346 	}, {
347 		.name = "tsecswrb",
348 		.sid = TEGRA186_SID_TSECB,
349 		.regs = {
350 			.override = 0x438,
351 			.security = 0x43c,
352 		},
353 	}, {
354 		.name = "gpusrd2",
355 		.sid = TEGRA186_SID_GPU,
356 		.regs = {
357 			.override = 0x440,
358 			.security = 0x444,
359 		},
360 	}, {
361 		.name = "gpuswr2",
362 		.sid = TEGRA186_SID_GPU,
363 		.regs = {
364 			.override = 0x448,
365 			.security = 0x44c,
366 		},
367 	}, {
368 		.name = "axisr",
369 		.sid = TEGRA186_SID_GPCDMA_0,
370 		.regs = {
371 			.override = 0x460,
372 			.security = 0x464,
373 		},
374 	}, {
375 		.name = "axisw",
376 		.sid = TEGRA186_SID_GPCDMA_0,
377 		.regs = {
378 			.override = 0x468,
379 			.security = 0x46c,
380 		},
381 	}, {
382 		.name = "eqosr",
383 		.sid = TEGRA186_SID_EQOS,
384 		.regs = {
385 			.override = 0x470,
386 			.security = 0x474,
387 		},
388 	}, {
389 		.name = "eqosw",
390 		.sid = TEGRA186_SID_EQOS,
391 		.regs = {
392 			.override = 0x478,
393 			.security = 0x47c,
394 		},
395 	}, {
396 		.name = "ufshcr",
397 		.sid = TEGRA186_SID_UFSHC,
398 		.regs = {
399 			.override = 0x480,
400 			.security = 0x484,
401 		},
402 	}, {
403 		.name = "ufshcw",
404 		.sid = TEGRA186_SID_UFSHC,
405 		.regs = {
406 			.override = 0x488,
407 			.security = 0x48c,
408 		},
409 	}, {
410 		.name = "nvdisplayr",
411 		.sid = TEGRA186_SID_NVDISPLAY,
412 		.regs = {
413 			.override = 0x490,
414 			.security = 0x494,
415 		},
416 	}, {
417 		.name = "bpmpr",
418 		.sid = TEGRA186_SID_BPMP,
419 		.regs = {
420 			.override = 0x498,
421 			.security = 0x49c,
422 		},
423 	}, {
424 		.name = "bpmpw",
425 		.sid = TEGRA186_SID_BPMP,
426 		.regs = {
427 			.override = 0x4a0,
428 			.security = 0x4a4,
429 		},
430 	}, {
431 		.name = "bpmpdmar",
432 		.sid = TEGRA186_SID_BPMP,
433 		.regs = {
434 			.override = 0x4a8,
435 			.security = 0x4ac,
436 		},
437 	}, {
438 		.name = "bpmpdmaw",
439 		.sid = TEGRA186_SID_BPMP,
440 		.regs = {
441 			.override = 0x4b0,
442 			.security = 0x4b4,
443 		},
444 	}, {
445 		.name = "aonr",
446 		.sid = TEGRA186_SID_AON,
447 		.regs = {
448 			.override = 0x4b8,
449 			.security = 0x4bc,
450 		},
451 	}, {
452 		.name = "aonw",
453 		.sid = TEGRA186_SID_AON,
454 		.regs = {
455 			.override = 0x4c0,
456 			.security = 0x4c4,
457 		},
458 	}, {
459 		.name = "aondmar",
460 		.sid = TEGRA186_SID_AON,
461 		.regs = {
462 			.override = 0x4c8,
463 			.security = 0x4cc,
464 		},
465 	}, {
466 		.name = "aondmaw",
467 		.sid = TEGRA186_SID_AON,
468 		.regs = {
469 			.override = 0x4d0,
470 			.security = 0x4d4,
471 		},
472 	}, {
473 		.name = "scer",
474 		.sid = TEGRA186_SID_SCE,
475 		.regs = {
476 			.override = 0x4d8,
477 			.security = 0x4dc,
478 		},
479 	}, {
480 		.name = "scew",
481 		.sid = TEGRA186_SID_SCE,
482 		.regs = {
483 			.override = 0x4e0,
484 			.security = 0x4e4,
485 		},
486 	}, {
487 		.name = "scedmar",
488 		.sid = TEGRA186_SID_SCE,
489 		.regs = {
490 			.override = 0x4e8,
491 			.security = 0x4ec,
492 		},
493 	}, {
494 		.name = "scedmaw",
495 		.sid = TEGRA186_SID_SCE,
496 		.regs = {
497 			.override = 0x4f0,
498 			.security = 0x4f4,
499 		},
500 	}, {
501 		.name = "apedmar",
502 		.sid = TEGRA186_SID_APE,
503 		.regs = {
504 			.override = 0x4f8,
505 			.security = 0x4fc,
506 		},
507 	}, {
508 		.name = "apedmaw",
509 		.sid = TEGRA186_SID_APE,
510 		.regs = {
511 			.override = 0x500,
512 			.security = 0x504,
513 		},
514 	}, {
515 		.name = "nvdisplayr1",
516 		.sid = TEGRA186_SID_NVDISPLAY,
517 		.regs = {
518 			.override = 0x508,
519 			.security = 0x50c,
520 		},
521 	}, {
522 		.name = "vicsrd1",
523 		.sid = TEGRA186_SID_VIC,
524 		.regs = {
525 			.override = 0x510,
526 			.security = 0x514,
527 		},
528 	}, {
529 		.name = "nvdecsrd1",
530 		.sid = TEGRA186_SID_NVDEC,
531 		.regs = {
532 			.override = 0x518,
533 			.security = 0x51c,
534 		},
535 	},
536 };
537 
538 static int tegra186_mc_probe(struct platform_device *pdev)
539 {
540 	struct resource *res;
541 	struct tegra_mc *mc;
542 	unsigned int i;
543 	int err = 0;
544 
545 	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
546 	if (!mc)
547 		return -ENOMEM;
548 
549 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
550 	mc->regs = devm_ioremap_resource(&pdev->dev, res);
551 	if (IS_ERR(mc->regs))
552 		return PTR_ERR(mc->regs);
553 
554 	mc->dev = &pdev->dev;
555 
556 	for (i = 0; i < ARRAY_SIZE(tegra186_mc_clients); i++) {
557 		const struct tegra_mc_client *client = &tegra186_mc_clients[i];
558 		u32 override, security;
559 
560 		override = readl(mc->regs + client->regs.override);
561 		security = readl(mc->regs + client->regs.security);
562 
563 		dev_dbg(&pdev->dev, "client %s: override: %x security: %x\n",
564 			client->name, override, security);
565 
566 		dev_dbg(&pdev->dev, "setting SID %u for %s\n", client->sid,
567 			client->name);
568 		writel(client->sid, mc->regs + client->regs.override);
569 
570 		override = readl(mc->regs + client->regs.override);
571 		security = readl(mc->regs + client->regs.security);
572 
573 		dev_dbg(&pdev->dev, "client %s: override: %x security: %x\n",
574 			client->name, override, security);
575 	}
576 
577 	platform_set_drvdata(pdev, mc);
578 
579 	return err;
580 }
581 
582 static const struct of_device_id tegra186_mc_of_match[] = {
583 	{ .compatible = "nvidia,tegra186-mc", },
584 	{ /* sentinel */ }
585 };
586 MODULE_DEVICE_TABLE(of, tegra186_mc_of_match);
587 
588 static struct platform_driver tegra186_mc_driver = {
589 	.driver = {
590 		.name = "tegra186-mc",
591 		.of_match_table = tegra186_mc_of_match,
592 		.suppress_bind_attrs = true,
593 	},
594 	.prevent_deferred_probe = true,
595 	.probe = tegra186_mc_probe,
596 };
597 module_platform_driver(tegra186_mc_driver);
598 
599 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
600 MODULE_DESCRIPTION("NVIDIA Tegra186 Memory Controller driver");
601 MODULE_LICENSE("GPL v2");
602