blob: a08b61a86760f03e4a3e31578a5ac5186867e13a [file] [log] [blame]
Thierry Reding89184652014-04-16 09:24:44 +02001/*
2 * Copyright (C) 2014 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/clk.h>
Dmitry Osipenko20e92462018-04-13 14:33:49 +030010#include <linux/delay.h>
Thierry Reding89184652014-04-16 09:24:44 +020011#include <linux/interrupt.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/of.h>
Dmitry Osipenko59cd0462018-12-12 23:38:54 +030015#include <linux/of_device.h>
Thierry Reding89184652014-04-16 09:24:44 +020016#include <linux/platform_device.h>
17#include <linux/slab.h>
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +010018#include <linux/sort.h>
19
20#include <soc/tegra/fuse.h>
Thierry Reding89184652014-04-16 09:24:44 +020021
22#include "mc.h"
23
24#define MC_INTSTATUS 0x000
Thierry Reding89184652014-04-16 09:24:44 +020025
26#define MC_INTMASK 0x004
27
28#define MC_ERR_STATUS 0x08
29#define MC_ERR_STATUS_TYPE_SHIFT 28
30#define MC_ERR_STATUS_TYPE_INVALID_SMMU_PAGE (6 << MC_ERR_STATUS_TYPE_SHIFT)
31#define MC_ERR_STATUS_TYPE_MASK (0x7 << MC_ERR_STATUS_TYPE_SHIFT)
32#define MC_ERR_STATUS_READABLE (1 << 27)
33#define MC_ERR_STATUS_WRITABLE (1 << 26)
34#define MC_ERR_STATUS_NONSECURE (1 << 25)
35#define MC_ERR_STATUS_ADR_HI_SHIFT 20
36#define MC_ERR_STATUS_ADR_HI_MASK 0x3
37#define MC_ERR_STATUS_SECURITY (1 << 17)
38#define MC_ERR_STATUS_RW (1 << 16)
Thierry Reding89184652014-04-16 09:24:44 +020039
40#define MC_ERR_ADR 0x0c
41
Dmitry Osipenkob3bb6b82018-12-12 23:38:53 +030042#define MC_GART_ERROR_REQ 0x30
Dmitry Osipenkoa8d502f2018-04-09 22:28:31 +030043#define MC_DECERR_EMEM_OTHERS_STATUS 0x58
44#define MC_SECURITY_VIOLATION_STATUS 0x74
45
Thierry Reding89184652014-04-16 09:24:44 +020046#define MC_EMEM_ARB_CFG 0x90
47#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(x) (((x) & 0x1ff) << 0)
48#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK 0x1ff
49#define MC_EMEM_ARB_MISC0 0xd8
50
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +010051#define MC_EMEM_ADR_CFG 0x54
52#define MC_EMEM_ADR_CFG_EMEM_NUMDEV BIT(0)
53
Thierry Reding89184652014-04-16 09:24:44 +020054static const struct of_device_id tegra_mc_of_match[] = {
Dmitry Osipenkoa8d502f2018-04-09 22:28:31 +030055#ifdef CONFIG_ARCH_TEGRA_2x_SOC
Dmitry Osipenko96efa112018-12-12 23:38:52 +030056 { .compatible = "nvidia,tegra20-mc-gart", .data = &tegra20_mc_soc },
Dmitry Osipenkoa8d502f2018-04-09 22:28:31 +030057#endif
Thierry Reding89184652014-04-16 09:24:44 +020058#ifdef CONFIG_ARCH_TEGRA_3x_SOC
59 { .compatible = "nvidia,tegra30-mc", .data = &tegra30_mc_soc },
60#endif
61#ifdef CONFIG_ARCH_TEGRA_114_SOC
62 { .compatible = "nvidia,tegra114-mc", .data = &tegra114_mc_soc },
63#endif
64#ifdef CONFIG_ARCH_TEGRA_124_SOC
65 { .compatible = "nvidia,tegra124-mc", .data = &tegra124_mc_soc },
66#endif
Thierry Reding242b1d72014-11-07 16:10:41 +010067#ifdef CONFIG_ARCH_TEGRA_132_SOC
68 { .compatible = "nvidia,tegra132-mc", .data = &tegra132_mc_soc },
69#endif
Thierry Reding588c43a2015-03-23 10:45:12 +010070#ifdef CONFIG_ARCH_TEGRA_210_SOC
71 { .compatible = "nvidia,tegra210-mc", .data = &tegra210_mc_soc },
72#endif
Thierry Reding89184652014-04-16 09:24:44 +020073 { }
74};
75MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
76
Thierry Redingcb2b5832019-04-11 10:48:25 +020077static int tegra_mc_block_dma_common(struct tegra_mc *mc,
Dmitry Osipenko20e92462018-04-13 14:33:49 +030078 const struct tegra_mc_reset *rst)
79{
80 unsigned long flags;
81 u32 value;
82
83 spin_lock_irqsave(&mc->lock, flags);
84
85 value = mc_readl(mc, rst->control) | BIT(rst->bit);
86 mc_writel(mc, value, rst->control);
87
88 spin_unlock_irqrestore(&mc->lock, flags);
89
90 return 0;
91}
92
Thierry Redingcb2b5832019-04-11 10:48:25 +020093static bool tegra_mc_dma_idling_common(struct tegra_mc *mc,
Dmitry Osipenko20e92462018-04-13 14:33:49 +030094 const struct tegra_mc_reset *rst)
95{
96 return (mc_readl(mc, rst->status) & BIT(rst->bit)) != 0;
97}
98
Thierry Redingcb2b5832019-04-11 10:48:25 +020099static int tegra_mc_unblock_dma_common(struct tegra_mc *mc,
Dmitry Osipenko20e92462018-04-13 14:33:49 +0300100 const struct tegra_mc_reset *rst)
101{
102 unsigned long flags;
103 u32 value;
104
105 spin_lock_irqsave(&mc->lock, flags);
106
107 value = mc_readl(mc, rst->control) & ~BIT(rst->bit);
108 mc_writel(mc, value, rst->control);
109
110 spin_unlock_irqrestore(&mc->lock, flags);
111
112 return 0;
113}
114
Thierry Redingcb2b5832019-04-11 10:48:25 +0200115static int tegra_mc_reset_status_common(struct tegra_mc *mc,
Dmitry Osipenko20e92462018-04-13 14:33:49 +0300116 const struct tegra_mc_reset *rst)
117{
118 return (mc_readl(mc, rst->control) & BIT(rst->bit)) != 0;
119}
120
Thierry Redingcb2b5832019-04-11 10:48:25 +0200121const struct tegra_mc_reset_ops tegra_mc_reset_ops_common = {
122 .block_dma = tegra_mc_block_dma_common,
123 .dma_idling = tegra_mc_dma_idling_common,
124 .unblock_dma = tegra_mc_unblock_dma_common,
125 .reset_status = tegra_mc_reset_status_common,
Dmitry Osipenko20e92462018-04-13 14:33:49 +0300126};
127
128static inline struct tegra_mc *reset_to_mc(struct reset_controller_dev *rcdev)
129{
130 return container_of(rcdev, struct tegra_mc, reset);
131}
132
133static const struct tegra_mc_reset *tegra_mc_reset_find(struct tegra_mc *mc,
134 unsigned long id)
135{
136 unsigned int i;
137
138 for (i = 0; i < mc->soc->num_resets; i++)
139 if (mc->soc->resets[i].id == id)
140 return &mc->soc->resets[i];
141
142 return NULL;
143}
144
145static int tegra_mc_hotreset_assert(struct reset_controller_dev *rcdev,
146 unsigned long id)
147{
148 struct tegra_mc *mc = reset_to_mc(rcdev);
149 const struct tegra_mc_reset_ops *rst_ops;
150 const struct tegra_mc_reset *rst;
151 int retries = 500;
152 int err;
153
154 rst = tegra_mc_reset_find(mc, id);
155 if (!rst)
156 return -ENODEV;
157
158 rst_ops = mc->soc->reset_ops;
159 if (!rst_ops)
160 return -ENODEV;
161
162 if (rst_ops->block_dma) {
163 /* block clients DMA requests */
164 err = rst_ops->block_dma(mc, rst);
165 if (err) {
Dmitry Osipenkof2dcded2018-12-12 23:38:59 +0300166 dev_err(mc->dev, "failed to block %s DMA: %d\n",
Dmitry Osipenko20e92462018-04-13 14:33:49 +0300167 rst->name, err);
168 return err;
169 }
170 }
171
172 if (rst_ops->dma_idling) {
173 /* wait for completion of the outstanding DMA requests */
174 while (!rst_ops->dma_idling(mc, rst)) {
175 if (!retries--) {
Dmitry Osipenkof2dcded2018-12-12 23:38:59 +0300176 dev_err(mc->dev, "failed to flush %s DMA\n",
Dmitry Osipenko20e92462018-04-13 14:33:49 +0300177 rst->name);
178 return -EBUSY;
179 }
180
181 usleep_range(10, 100);
182 }
183 }
184
185 if (rst_ops->hotreset_assert) {
186 /* clear clients DMA requests sitting before arbitration */
187 err = rst_ops->hotreset_assert(mc, rst);
188 if (err) {
Dmitry Osipenkof2dcded2018-12-12 23:38:59 +0300189 dev_err(mc->dev, "failed to hot reset %s: %d\n",
Dmitry Osipenko20e92462018-04-13 14:33:49 +0300190 rst->name, err);
191 return err;
192 }
193 }
194
195 return 0;
196}
197
198static int tegra_mc_hotreset_deassert(struct reset_controller_dev *rcdev,
199 unsigned long id)
200{
201 struct tegra_mc *mc = reset_to_mc(rcdev);
202 const struct tegra_mc_reset_ops *rst_ops;
203 const struct tegra_mc_reset *rst;
204 int err;
205
206 rst = tegra_mc_reset_find(mc, id);
207 if (!rst)
208 return -ENODEV;
209
210 rst_ops = mc->soc->reset_ops;
211 if (!rst_ops)
212 return -ENODEV;
213
214 if (rst_ops->hotreset_deassert) {
215 /* take out client from hot reset */
216 err = rst_ops->hotreset_deassert(mc, rst);
217 if (err) {
Dmitry Osipenkof2dcded2018-12-12 23:38:59 +0300218 dev_err(mc->dev, "failed to deassert hot reset %s: %d\n",
Dmitry Osipenko20e92462018-04-13 14:33:49 +0300219 rst->name, err);
220 return err;
221 }
222 }
223
224 if (rst_ops->unblock_dma) {
225 /* allow new DMA requests to proceed to arbitration */
226 err = rst_ops->unblock_dma(mc, rst);
227 if (err) {
Dmitry Osipenkof2dcded2018-12-12 23:38:59 +0300228 dev_err(mc->dev, "failed to unblock %s DMA : %d\n",
Dmitry Osipenko20e92462018-04-13 14:33:49 +0300229 rst->name, err);
230 return err;
231 }
232 }
233
234 return 0;
235}
236
237static int tegra_mc_hotreset_status(struct reset_controller_dev *rcdev,
238 unsigned long id)
239{
240 struct tegra_mc *mc = reset_to_mc(rcdev);
241 const struct tegra_mc_reset_ops *rst_ops;
242 const struct tegra_mc_reset *rst;
243
244 rst = tegra_mc_reset_find(mc, id);
245 if (!rst)
246 return -ENODEV;
247
248 rst_ops = mc->soc->reset_ops;
249 if (!rst_ops)
250 return -ENODEV;
251
252 return rst_ops->reset_status(mc, rst);
253}
254
255static const struct reset_control_ops tegra_mc_reset_ops = {
256 .assert = tegra_mc_hotreset_assert,
257 .deassert = tegra_mc_hotreset_deassert,
258 .status = tegra_mc_hotreset_status,
259};
260
261static int tegra_mc_reset_setup(struct tegra_mc *mc)
262{
263 int err;
264
265 mc->reset.ops = &tegra_mc_reset_ops;
266 mc->reset.owner = THIS_MODULE;
267 mc->reset.of_node = mc->dev->of_node;
268 mc->reset.of_reset_n_cells = 1;
269 mc->reset.nr_resets = mc->soc->num_resets;
270
271 err = reset_controller_register(&mc->reset);
272 if (err < 0)
273 return err;
274
275 return 0;
276}
277
Thierry Reding89184652014-04-16 09:24:44 +0200278static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
279{
280 unsigned long long tick;
281 unsigned int i;
282 u32 value;
283
284 /* compute the number of MC clock cycles per tick */
285 tick = mc->tick * clk_get_rate(mc->clk);
286 do_div(tick, NSEC_PER_SEC);
287
288 value = readl(mc->regs + MC_EMEM_ARB_CFG);
289 value &= ~MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK;
290 value |= MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(tick);
291 writel(value, mc->regs + MC_EMEM_ARB_CFG);
292
293 /* write latency allowance defaults */
294 for (i = 0; i < mc->soc->num_clients; i++) {
295 const struct tegra_mc_la *la = &mc->soc->clients[i].la;
296 u32 value;
297
298 value = readl(mc->regs + la->reg);
299 value &= ~(la->mask << la->shift);
300 value |= (la->def & la->mask) << la->shift;
301 writel(value, mc->regs + la->reg);
302 }
303
304 return 0;
305}
306
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100307void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate)
308{
309 unsigned int i;
310 struct tegra_mc_timing *timing = NULL;
311
312 for (i = 0; i < mc->num_timings; i++) {
313 if (mc->timings[i].rate == rate) {
314 timing = &mc->timings[i];
315 break;
316 }
317 }
318
319 if (!timing) {
320 dev_err(mc->dev, "no memory timing registered for rate %lu\n",
321 rate);
322 return;
323 }
324
325 for (i = 0; i < mc->soc->num_emem_regs; ++i)
326 mc_writel(mc, timing->emem_data[i], mc->soc->emem_regs[i]);
327}
328
329unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc)
330{
331 u8 dram_count;
332
333 dram_count = mc_readl(mc, MC_EMEM_ADR_CFG);
334 dram_count &= MC_EMEM_ADR_CFG_EMEM_NUMDEV;
335 dram_count++;
336
337 return dram_count;
338}
339
340static int load_one_timing(struct tegra_mc *mc,
341 struct tegra_mc_timing *timing,
342 struct device_node *node)
343{
344 int err;
345 u32 tmp;
346
347 err = of_property_read_u32(node, "clock-frequency", &tmp);
348 if (err) {
349 dev_err(mc->dev,
Rob Herringc86f9852018-08-27 19:57:23 -0500350 "timing %pOFn: failed to read rate\n", node);
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100351 return err;
352 }
353
354 timing->rate = tmp;
355 timing->emem_data = devm_kcalloc(mc->dev, mc->soc->num_emem_regs,
356 sizeof(u32), GFP_KERNEL);
357 if (!timing->emem_data)
358 return -ENOMEM;
359
360 err = of_property_read_u32_array(node, "nvidia,emem-configuration",
361 timing->emem_data,
362 mc->soc->num_emem_regs);
363 if (err) {
364 dev_err(mc->dev,
Rob Herringc86f9852018-08-27 19:57:23 -0500365 "timing %pOFn: failed to read EMEM configuration\n",
366 node);
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100367 return err;
368 }
369
370 return 0;
371}
372
373static int load_timings(struct tegra_mc *mc, struct device_node *node)
374{
375 struct device_node *child;
376 struct tegra_mc_timing *timing;
377 int child_count = of_get_child_count(node);
378 int i = 0, err;
379
380 mc->timings = devm_kcalloc(mc->dev, child_count, sizeof(*timing),
381 GFP_KERNEL);
382 if (!mc->timings)
383 return -ENOMEM;
384
385 mc->num_timings = child_count;
386
387 for_each_child_of_node(node, child) {
388 timing = &mc->timings[i++];
389
390 err = load_one_timing(mc, timing, child);
Amitoj Kaur Chawla55bb1d82016-01-25 22:53:07 +0530391 if (err) {
392 of_node_put(child);
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100393 return err;
Amitoj Kaur Chawla55bb1d82016-01-25 22:53:07 +0530394 }
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100395 }
396
397 return 0;
398}
399
400static int tegra_mc_setup_timings(struct tegra_mc *mc)
401{
402 struct device_node *node;
403 u32 ram_code, node_ram_code;
404 int err;
405
406 ram_code = tegra_read_ram_code();
407
408 mc->num_timings = 0;
409
410 for_each_child_of_node(mc->dev->of_node, node) {
411 err = of_property_read_u32(node, "nvidia,ram-code",
412 &node_ram_code);
Julia Lawalld1122e42015-10-09 19:47:40 +0200413 if (err || (node_ram_code != ram_code))
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100414 continue;
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100415
416 err = load_timings(mc, node);
Amitoj Kaur Chawla55bb1d82016-01-25 22:53:07 +0530417 of_node_put(node);
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100418 if (err)
419 return err;
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100420 break;
421 }
422
423 if (mc->num_timings == 0)
424 dev_warn(mc->dev,
425 "no memory timings for RAM code %u registered\n",
426 ram_code);
427
428 return 0;
429}
430
Thierry Reding89184652014-04-16 09:24:44 +0200431static const char *const status_names[32] = {
432 [ 1] = "External interrupt",
433 [ 6] = "EMEM address decode error",
Dmitry Osipenkoa8d502f2018-04-09 22:28:31 +0300434 [ 7] = "GART page fault",
Thierry Reding89184652014-04-16 09:24:44 +0200435 [ 8] = "Security violation",
436 [ 9] = "EMEM arbitration error",
437 [10] = "Page fault",
438 [11] = "Invalid APB ASID update",
439 [12] = "VPR violation",
440 [13] = "Secure carveout violation",
441 [16] = "MTS carveout violation",
442};
443
444static const char *const error_names[8] = {
445 [2] = "EMEM decode error",
446 [3] = "TrustZone violation",
447 [4] = "Carveout violation",
448 [6] = "SMMU translation error",
449};
450
451static irqreturn_t tegra_mc_irq(int irq, void *data)
452{
453 struct tegra_mc *mc = data;
Dmitry Osipenko1c74d5c2018-04-09 22:28:29 +0300454 unsigned long status;
Thierry Reding89184652014-04-16 09:24:44 +0200455 unsigned int bit;
456
457 /* mask all interrupts to avoid flooding */
Dmitry Osipenko1c74d5c2018-04-09 22:28:29 +0300458 status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask;
Dmitry Osipenkobf3fbdf2018-04-09 22:28:27 +0300459 if (!status)
460 return IRQ_NONE;
Thierry Reding89184652014-04-16 09:24:44 +0200461
462 for_each_set_bit(bit, &status, 32) {
463 const char *error = status_names[bit] ?: "unknown";
464 const char *client = "unknown", *desc;
465 const char *direction, *secure;
466 phys_addr_t addr = 0;
467 unsigned int i;
468 char perm[7];
469 u8 id, type;
470 u32 value;
471
472 value = mc_readl(mc, MC_ERR_STATUS);
473
474#ifdef CONFIG_PHYS_ADDR_T_64BIT
475 if (mc->soc->num_address_bits > 32) {
476 addr = ((value >> MC_ERR_STATUS_ADR_HI_SHIFT) &
477 MC_ERR_STATUS_ADR_HI_MASK);
478 addr <<= 32;
479 }
480#endif
481
482 if (value & MC_ERR_STATUS_RW)
483 direction = "write";
484 else
485 direction = "read";
486
487 if (value & MC_ERR_STATUS_SECURITY)
488 secure = "secure ";
489 else
490 secure = "";
491
Paul Walmsley3c01cf32015-06-04 19:33:48 +0000492 id = value & mc->soc->client_id_mask;
Thierry Reding89184652014-04-16 09:24:44 +0200493
494 for (i = 0; i < mc->soc->num_clients; i++) {
495 if (mc->soc->clients[i].id == id) {
496 client = mc->soc->clients[i].name;
497 break;
498 }
499 }
500
501 type = (value & MC_ERR_STATUS_TYPE_MASK) >>
502 MC_ERR_STATUS_TYPE_SHIFT;
503 desc = error_names[type];
504
505 switch (value & MC_ERR_STATUS_TYPE_MASK) {
506 case MC_ERR_STATUS_TYPE_INVALID_SMMU_PAGE:
507 perm[0] = ' ';
508 perm[1] = '[';
509
510 if (value & MC_ERR_STATUS_READABLE)
511 perm[2] = 'R';
512 else
513 perm[2] = '-';
514
515 if (value & MC_ERR_STATUS_WRITABLE)
516 perm[3] = 'W';
517 else
518 perm[3] = '-';
519
520 if (value & MC_ERR_STATUS_NONSECURE)
521 perm[4] = '-';
522 else
523 perm[4] = 'S';
524
525 perm[5] = ']';
526 perm[6] = '\0';
527 break;
528
529 default:
530 perm[0] = '\0';
531 break;
532 }
533
534 value = mc_readl(mc, MC_ERR_ADR);
535 addr |= value;
536
537 dev_err_ratelimited(mc->dev, "%s: %s%s @%pa: %s (%s%s)\n",
538 client, secure, direction, &addr, error,
539 desc, perm);
540 }
541
542 /* clear interrupts */
543 mc_writel(mc, status, MC_INTSTATUS);
544
545 return IRQ_HANDLED;
546}
547
Dmitry Osipenkoa8d502f2018-04-09 22:28:31 +0300548static __maybe_unused irqreturn_t tegra20_mc_irq(int irq, void *data)
549{
550 struct tegra_mc *mc = data;
551 unsigned long status;
552 unsigned int bit;
553
554 /* mask all interrupts to avoid flooding */
555 status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask;
556 if (!status)
557 return IRQ_NONE;
558
559 for_each_set_bit(bit, &status, 32) {
560 const char *direction = "read", *secure = "";
561 const char *error = status_names[bit];
562 const char *client, *desc;
563 phys_addr_t addr;
564 u32 value, reg;
565 u8 id, type;
566
567 switch (BIT(bit)) {
568 case MC_INT_DECERR_EMEM:
569 reg = MC_DECERR_EMEM_OTHERS_STATUS;
570 value = mc_readl(mc, reg);
571
572 id = value & mc->soc->client_id_mask;
573 desc = error_names[2];
574
575 if (value & BIT(31))
576 direction = "write";
577 break;
578
579 case MC_INT_INVALID_GART_PAGE:
Dmitry Osipenkob3bb6b82018-12-12 23:38:53 +0300580 reg = MC_GART_ERROR_REQ;
581 value = mc_readl(mc, reg);
582
583 id = (value >> 1) & mc->soc->client_id_mask;
584 desc = error_names[2];
585
586 if (value & BIT(0))
587 direction = "write";
588 break;
Dmitry Osipenkoa8d502f2018-04-09 22:28:31 +0300589
590 case MC_INT_SECURITY_VIOLATION:
591 reg = MC_SECURITY_VIOLATION_STATUS;
592 value = mc_readl(mc, reg);
593
594 id = value & mc->soc->client_id_mask;
595 type = (value & BIT(30)) ? 4 : 3;
596 desc = error_names[type];
597 secure = "secure ";
598
599 if (value & BIT(31))
600 direction = "write";
601 break;
602
603 default:
604 continue;
605 }
606
607 client = mc->soc->clients[id].name;
608 addr = mc_readl(mc, reg + sizeof(u32));
609
610 dev_err_ratelimited(mc->dev, "%s: %s%s @%pa: %s (%s)\n",
611 client, secure, direction, &addr, error,
612 desc);
613 }
614
615 /* clear interrupts */
616 mc_writel(mc, status, MC_INTSTATUS);
617
618 return IRQ_HANDLED;
619}
620
Thierry Reding89184652014-04-16 09:24:44 +0200621static int tegra_mc_probe(struct platform_device *pdev)
622{
Thierry Reding89184652014-04-16 09:24:44 +0200623 struct resource *res;
624 struct tegra_mc *mc;
Dmitry Osipenkoa8d502f2018-04-09 22:28:31 +0300625 void *isr;
Thierry Reding89184652014-04-16 09:24:44 +0200626 int err;
627
Thierry Reding89184652014-04-16 09:24:44 +0200628 mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
629 if (!mc)
630 return -ENOMEM;
631
632 platform_set_drvdata(pdev, mc);
Dmitry Osipenko20e92462018-04-13 14:33:49 +0300633 spin_lock_init(&mc->lock);
Dmitry Osipenko59cd0462018-12-12 23:38:54 +0300634 mc->soc = of_device_get_match_data(&pdev->dev);
Thierry Reding89184652014-04-16 09:24:44 +0200635 mc->dev = &pdev->dev;
636
637 /* length of MC tick in nanoseconds */
638 mc->tick = 30;
639
640 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
641 mc->regs = devm_ioremap_resource(&pdev->dev, res);
642 if (IS_ERR(mc->regs))
643 return PTR_ERR(mc->regs);
644
Dmitry Osipenko96efa112018-12-12 23:38:52 +0300645 mc->clk = devm_clk_get(&pdev->dev, "mc");
646 if (IS_ERR(mc->clk)) {
647 dev_err(&pdev->dev, "failed to get MC clock: %ld\n",
648 PTR_ERR(mc->clk));
649 return PTR_ERR(mc->clk);
650 }
651
Dmitry Osipenkoa8d502f2018-04-09 22:28:31 +0300652#ifdef CONFIG_ARCH_TEGRA_2x_SOC
653 if (mc->soc == &tegra20_mc_soc) {
Dmitry Osipenkoa8d502f2018-04-09 22:28:31 +0300654 isr = tegra20_mc_irq;
655 } else
656#endif
657 {
Dmitry Osipenkoa8d502f2018-04-09 22:28:31 +0300658 err = tegra_mc_setup_latency_allowance(mc);
659 if (err < 0) {
Dmitry Osipenkof2dcded2018-12-12 23:38:59 +0300660 dev_err(&pdev->dev,
661 "failed to setup latency allowance: %d\n",
Dmitry Osipenkoa8d502f2018-04-09 22:28:31 +0300662 err);
663 return err;
664 }
665
666 isr = tegra_mc_irq;
Thierry Reding89184652014-04-16 09:24:44 +0200667
Dmitry Osipenkobe4dbde2018-12-12 23:38:51 +0300668 err = tegra_mc_setup_timings(mc);
669 if (err < 0) {
670 dev_err(&pdev->dev, "failed to setup timings: %d\n",
671 err);
672 return err;
673 }
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100674 }
675
Thierry Reding89184652014-04-16 09:24:44 +0200676 mc->irq = platform_get_irq(pdev, 0);
677 if (mc->irq < 0) {
678 dev_err(&pdev->dev, "interrupt not specified\n");
679 return mc->irq;
680 }
681
Dmitry Osipenkof2dcded2018-12-12 23:38:59 +0300682 WARN(!mc->soc->client_id_mask, "missing client ID mask for this SoC\n");
Paul Walmsley3c01cf32015-06-04 19:33:48 +0000683
Dmitry Osipenko1c74d5c2018-04-09 22:28:29 +0300684 mc_writel(mc, mc->soc->intmask, MC_INTMASK);
Thierry Reding89184652014-04-16 09:24:44 +0200685
Dmitry Osipenko33ea0022018-12-12 23:38:58 +0300686 err = devm_request_irq(&pdev->dev, mc->irq, isr, 0,
Dmitry Osipenkodb4a9c12018-04-09 22:28:28 +0300687 dev_name(&pdev->dev), mc);
688 if (err < 0) {
689 dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", mc->irq,
690 err);
691 return err;
692 }
693
Dmitry Osipenko1662dd62018-05-26 17:20:35 +0300694 err = tegra_mc_reset_setup(mc);
695 if (err < 0)
696 dev_err(&pdev->dev, "failed to register reset controller: %d\n",
697 err);
698
Dmitry Osipenko568ece52018-12-12 23:38:57 +0300699 if (IS_ENABLED(CONFIG_TEGRA_IOMMU_SMMU) && mc->soc->smmu) {
Dmitry Osipenko45a81df2018-05-08 19:55:30 +0300700 mc->smmu = tegra_smmu_probe(&pdev->dev, mc->soc->smmu, mc);
Dmitry Osipenko568ece52018-12-12 23:38:57 +0300701 if (IS_ERR(mc->smmu)) {
Dmitry Osipenko45a81df2018-05-08 19:55:30 +0300702 dev_err(&pdev->dev, "failed to probe SMMU: %ld\n",
703 PTR_ERR(mc->smmu));
Dmitry Osipenko568ece52018-12-12 23:38:57 +0300704 mc->smmu = NULL;
705 }
Dmitry Osipenko45a81df2018-05-08 19:55:30 +0300706 }
707
Dmitry Osipenkoce2785a2018-12-12 23:38:56 +0300708 if (IS_ENABLED(CONFIG_TEGRA_IOMMU_GART) && !mc->soc->smmu) {
709 mc->gart = tegra_gart_probe(&pdev->dev, mc);
710 if (IS_ERR(mc->gart)) {
711 dev_err(&pdev->dev, "failed to probe GART: %ld\n",
712 PTR_ERR(mc->gart));
713 mc->gart = NULL;
714 }
715 }
716
Thierry Reding89184652014-04-16 09:24:44 +0200717 return 0;
718}
719
Dmitry Osipenkoce2785a2018-12-12 23:38:56 +0300720static int tegra_mc_suspend(struct device *dev)
721{
722 struct tegra_mc *mc = dev_get_drvdata(dev);
723 int err;
724
725 if (IS_ENABLED(CONFIG_TEGRA_IOMMU_GART) && mc->gart) {
726 err = tegra_gart_suspend(mc->gart);
727 if (err)
728 return err;
729 }
730
731 return 0;
732}
733
734static int tegra_mc_resume(struct device *dev)
735{
736 struct tegra_mc *mc = dev_get_drvdata(dev);
737 int err;
738
739 if (IS_ENABLED(CONFIG_TEGRA_IOMMU_GART) && mc->gart) {
740 err = tegra_gart_resume(mc->gart);
741 if (err)
742 return err;
743 }
744
745 return 0;
746}
747
748static const struct dev_pm_ops tegra_mc_pm_ops = {
749 .suspend = tegra_mc_suspend,
750 .resume = tegra_mc_resume,
751};
752
Thierry Reding89184652014-04-16 09:24:44 +0200753static struct platform_driver tegra_mc_driver = {
754 .driver = {
755 .name = "tegra-mc",
756 .of_match_table = tegra_mc_of_match,
Dmitry Osipenkoce2785a2018-12-12 23:38:56 +0300757 .pm = &tegra_mc_pm_ops,
Thierry Reding89184652014-04-16 09:24:44 +0200758 .suppress_bind_attrs = true,
759 },
760 .prevent_deferred_probe = true,
761 .probe = tegra_mc_probe,
762};
763
764static int tegra_mc_init(void)
765{
766 return platform_driver_register(&tegra_mc_driver);
767}
768arch_initcall(tegra_mc_init);
769
770MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
771MODULE_DESCRIPTION("NVIDIA Tegra Memory Controller driver");
772MODULE_LICENSE("GPL v2");