1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
6 #include <linux/bitfield.h>
7 #include <linux/delay.h>
8 #include <linux/device.h>
9 #include <linux/mutex.h>
11 #include <linux/slab.h>
12 #include <linux/string.h>
14 #include <dt-bindings/memory/tegra20-mc.h>
18 #define MC_STAT_CONTROL 0x90
19 #define MC_STAT_EMC_CLOCK_LIMIT 0xa0
20 #define MC_STAT_EMC_CLOCKS 0xa4
21 #define MC_STAT_EMC_CONTROL_0 0xa8
22 #define MC_STAT_EMC_CONTROL_1 0xac
23 #define MC_STAT_EMC_COUNT_0 0xb8
24 #define MC_STAT_EMC_COUNT_1 0xbc
26 #define MC_STAT_CONTROL_CLIENT_ID GENMASK(13, 8)
27 #define MC_STAT_CONTROL_EVENT GENMASK(23, 16)
28 #define MC_STAT_CONTROL_PRI_EVENT GENMASK(25, 24)
29 #define MC_STAT_CONTROL_FILTER_CLIENT_ENABLE GENMASK(26, 26)
30 #define MC_STAT_CONTROL_FILTER_PRI GENMASK(29, 28)
32 #define MC_STAT_CONTROL_PRI_EVENT_HP 0
33 #define MC_STAT_CONTROL_PRI_EVENT_TM 1
34 #define MC_STAT_CONTROL_PRI_EVENT_BW 2
36 #define MC_STAT_CONTROL_FILTER_PRI_DISABLE 0
37 #define MC_STAT_CONTROL_FILTER_PRI_NO 1
38 #define MC_STAT_CONTROL_FILTER_PRI_YES 2
40 #define MC_STAT_CONTROL_EVENT_QUALIFIED 0
41 #define MC_STAT_CONTROL_EVENT_ANY_READ 1
42 #define MC_STAT_CONTROL_EVENT_ANY_WRITE 2
43 #define MC_STAT_CONTROL_EVENT_RD_WR_CHANGE 3
44 #define MC_STAT_CONTROL_EVENT_SUCCESSIVE 4
45 #define MC_STAT_CONTROL_EVENT_ARB_BANK_AA 5
46 #define MC_STAT_CONTROL_EVENT_ARB_BANK_BB 6
47 #define MC_STAT_CONTROL_EVENT_PAGE_MISS 7
48 #define MC_STAT_CONTROL_EVENT_AUTO_PRECHARGE 8
50 #define EMC_GATHER_RST (0 << 8)
51 #define EMC_GATHER_CLEAR (1 << 8)
52 #define EMC_GATHER_DISABLE (2 << 8)
53 #define EMC_GATHER_ENABLE (3 << 8)
55 #define MC_STAT_SAMPLE_TIME_USEC 16000
57 /* we store collected statistics as a fixed point values */
58 #define MC_FX_FRAC_SCALE 100
60 static DEFINE_MUTEX(tegra20_mc_stat_lock
);
62 struct tegra20_mc_stat_gather
{
63 unsigned int pri_filter
;
64 unsigned int pri_event
;
71 struct tegra20_mc_stat
{
72 struct tegra20_mc_stat_gather gather0
;
73 struct tegra20_mc_stat_gather gather1
;
74 unsigned int sample_time_usec
;
75 const struct tegra_mc
*mc
;
78 struct tegra20_mc_client_stat
{
80 unsigned int arb_high_prio
;
81 unsigned int arb_timeout
;
82 unsigned int arb_bandwidth
;
83 unsigned int rd_wr_change
;
84 unsigned int successive
;
85 unsigned int page_miss
;
86 unsigned int auto_precharge
;
87 unsigned int arb_bank_aa
;
88 unsigned int arb_bank_bb
;
91 static const struct tegra_mc_client tegra20_mc_clients
[] = {
103 .name
= "display0bb",
109 .name
= "display0cb",
115 .name
= "display1bb",
139 .name
= "displayhcb",
148 .name
= "host1xdmar",
169 .name
= "ppcsahbdmar",
172 .name
= "ppcsahbslvr",
235 .name
= "ppcsahbdmaw",
238 .name
= "ppcsahbslvw",
251 #define TEGRA20_MC_RESET(_name, _control, _status, _reset, _bit) \
254 .id = TEGRA20_MC_RESET_##_name, \
255 .control = _control, \
261 static const struct tegra_mc_reset tegra20_mc_resets
[] = {
262 TEGRA20_MC_RESET(AVPC
, 0x100, 0x140, 0x104, 0),
263 TEGRA20_MC_RESET(DC
, 0x100, 0x144, 0x104, 1),
264 TEGRA20_MC_RESET(DCB
, 0x100, 0x148, 0x104, 2),
265 TEGRA20_MC_RESET(EPP
, 0x100, 0x14c, 0x104, 3),
266 TEGRA20_MC_RESET(2D
, 0x100, 0x150, 0x104, 4),
267 TEGRA20_MC_RESET(HC
, 0x100, 0x154, 0x104, 5),
268 TEGRA20_MC_RESET(ISP
, 0x100, 0x158, 0x104, 6),
269 TEGRA20_MC_RESET(MPCORE
, 0x100, 0x15c, 0x104, 7),
270 TEGRA20_MC_RESET(MPEA
, 0x100, 0x160, 0x104, 8),
271 TEGRA20_MC_RESET(MPEB
, 0x100, 0x164, 0x104, 9),
272 TEGRA20_MC_RESET(MPEC
, 0x100, 0x168, 0x104, 10),
273 TEGRA20_MC_RESET(3D
, 0x100, 0x16c, 0x104, 11),
274 TEGRA20_MC_RESET(PPCS
, 0x100, 0x170, 0x104, 12),
275 TEGRA20_MC_RESET(VDE
, 0x100, 0x174, 0x104, 13),
276 TEGRA20_MC_RESET(VI
, 0x100, 0x178, 0x104, 14),
279 static int tegra20_mc_hotreset_assert(struct tegra_mc
*mc
,
280 const struct tegra_mc_reset
*rst
)
285 spin_lock_irqsave(&mc
->lock
, flags
);
287 value
= mc_readl(mc
, rst
->reset
);
288 mc_writel(mc
, value
& ~BIT(rst
->bit
), rst
->reset
);
290 spin_unlock_irqrestore(&mc
->lock
, flags
);
295 static int tegra20_mc_hotreset_deassert(struct tegra_mc
*mc
,
296 const struct tegra_mc_reset
*rst
)
301 spin_lock_irqsave(&mc
->lock
, flags
);
303 value
= mc_readl(mc
, rst
->reset
);
304 mc_writel(mc
, value
| BIT(rst
->bit
), rst
->reset
);
306 spin_unlock_irqrestore(&mc
->lock
, flags
);
311 static int tegra20_mc_block_dma(struct tegra_mc
*mc
,
312 const struct tegra_mc_reset
*rst
)
317 spin_lock_irqsave(&mc
->lock
, flags
);
319 value
= mc_readl(mc
, rst
->control
) & ~BIT(rst
->bit
);
320 mc_writel(mc
, value
, rst
->control
);
322 spin_unlock_irqrestore(&mc
->lock
, flags
);
327 static bool tegra20_mc_dma_idling(struct tegra_mc
*mc
,
328 const struct tegra_mc_reset
*rst
)
330 return mc_readl(mc
, rst
->status
) == 0;
333 static int tegra20_mc_reset_status(struct tegra_mc
*mc
,
334 const struct tegra_mc_reset
*rst
)
336 return (mc_readl(mc
, rst
->reset
) & BIT(rst
->bit
)) == 0;
339 static int tegra20_mc_unblock_dma(struct tegra_mc
*mc
,
340 const struct tegra_mc_reset
*rst
)
345 spin_lock_irqsave(&mc
->lock
, flags
);
347 value
= mc_readl(mc
, rst
->control
) | BIT(rst
->bit
);
348 mc_writel(mc
, value
, rst
->control
);
350 spin_unlock_irqrestore(&mc
->lock
, flags
);
355 static const struct tegra_mc_reset_ops tegra20_mc_reset_ops
= {
356 .hotreset_assert
= tegra20_mc_hotreset_assert
,
357 .hotreset_deassert
= tegra20_mc_hotreset_deassert
,
358 .block_dma
= tegra20_mc_block_dma
,
359 .dma_idling
= tegra20_mc_dma_idling
,
360 .unblock_dma
= tegra20_mc_unblock_dma
,
361 .reset_status
= tegra20_mc_reset_status
,
364 static int tegra20_mc_icc_set(struct icc_node
*src
, struct icc_node
*dst
)
367 * It should be possible to tune arbitration knobs here, but the
368 * default values are known to work well on all devices. Hence
369 * nothing to do here so far.
374 static int tegra20_mc_icc_aggreate(struct icc_node
*node
, u32 tag
, u32 avg_bw
,
375 u32 peak_bw
, u32
*agg_avg
, u32
*agg_peak
)
378 * ISO clients need to reserve extra bandwidth up-front because
379 * there could be high bandwidth pressure during initial filling
380 * of the client's FIFO buffers. Secondly, we need to take into
381 * account impurities of the memory subsystem.
383 if (tag
& TEGRA_MC_ICC_TAG_ISO
)
384 peak_bw
= tegra_mc_scale_percents(peak_bw
, 300);
387 *agg_peak
= max(*agg_peak
, peak_bw
);
392 static struct icc_node_data
*
393 tegra20_mc_of_icc_xlate_extended(const struct of_phandle_args
*spec
, void *data
)
395 struct tegra_mc
*mc
= icc_provider_to_tegra_mc(data
);
396 unsigned int i
, idx
= spec
->args
[0];
397 struct icc_node_data
*ndata
;
398 struct icc_node
*node
;
400 list_for_each_entry(node
, &mc
->provider
.nodes
, node_list
) {
404 ndata
= kzalloc(sizeof(*ndata
), GFP_KERNEL
);
406 return ERR_PTR(-ENOMEM
);
410 /* these clients are isochronous by default */
411 if (strstarts(node
->name
, "display") ||
412 strstarts(node
->name
, "vi"))
413 ndata
->tag
= TEGRA_MC_ICC_TAG_ISO
;
415 ndata
->tag
= TEGRA_MC_ICC_TAG_DEFAULT
;
420 for (i
= 0; i
< mc
->soc
->num_clients
; i
++) {
421 if (mc
->soc
->clients
[i
].id
== idx
)
422 return ERR_PTR(-EPROBE_DEFER
);
425 dev_err(mc
->dev
, "invalid ICC client ID %u\n", idx
);
427 return ERR_PTR(-EINVAL
);
430 static const struct tegra_mc_icc_ops tegra20_mc_icc_ops
= {
431 .xlate_extended
= tegra20_mc_of_icc_xlate_extended
,
432 .aggregate
= tegra20_mc_icc_aggreate
,
433 .set
= tegra20_mc_icc_set
,
436 static u32
tegra20_mc_stat_gather_control(const struct tegra20_mc_stat_gather
*g
)
440 control
= FIELD_PREP(MC_STAT_CONTROL_EVENT
, g
->event
);
441 control
|= FIELD_PREP(MC_STAT_CONTROL_CLIENT_ID
, g
->client
);
442 control
|= FIELD_PREP(MC_STAT_CONTROL_PRI_EVENT
, g
->pri_event
);
443 control
|= FIELD_PREP(MC_STAT_CONTROL_FILTER_PRI
, g
->pri_filter
);
444 control
|= FIELD_PREP(MC_STAT_CONTROL_FILTER_CLIENT_ENABLE
, g
->client_enb
);
449 static void tegra20_mc_stat_gather(struct tegra20_mc_stat
*stat
)
451 u32 clocks
, count0
, count1
, control_0
, control_1
;
452 const struct tegra_mc
*mc
= stat
->mc
;
454 control_0
= tegra20_mc_stat_gather_control(&stat
->gather0
);
455 control_1
= tegra20_mc_stat_gather_control(&stat
->gather1
);
458 * Reset statistic gathers state, select statistics collection mode
459 * and set clocks counter saturation limit to maximum.
461 mc_writel(mc
, 0x00000000, MC_STAT_CONTROL
);
462 mc_writel(mc
, control_0
, MC_STAT_EMC_CONTROL_0
);
463 mc_writel(mc
, control_1
, MC_STAT_EMC_CONTROL_1
);
464 mc_writel(mc
, 0xffffffff, MC_STAT_EMC_CLOCK_LIMIT
);
466 mc_writel(mc
, EMC_GATHER_ENABLE
, MC_STAT_CONTROL
);
467 fsleep(stat
->sample_time_usec
);
468 mc_writel(mc
, EMC_GATHER_DISABLE
, MC_STAT_CONTROL
);
470 count0
= mc_readl(mc
, MC_STAT_EMC_COUNT_0
);
471 count1
= mc_readl(mc
, MC_STAT_EMC_COUNT_1
);
472 clocks
= mc_readl(mc
, MC_STAT_EMC_CLOCKS
);
473 clocks
= max(clocks
/ 100 / MC_FX_FRAC_SCALE
, 1u);
475 stat
->gather0
.result
= DIV_ROUND_UP(count0
, clocks
);
476 stat
->gather1
.result
= DIV_ROUND_UP(count1
, clocks
);
479 static void tegra20_mc_stat_events(const struct tegra_mc
*mc
,
480 const struct tegra_mc_client
*client0
,
481 const struct tegra_mc_client
*client1
,
482 unsigned int pri_filter
,
483 unsigned int pri_event
,
485 unsigned int *result0
,
486 unsigned int *result1
)
488 struct tegra20_mc_stat stat
= {};
490 stat
.gather0
.client
= client0
? client0
->id
: 0;
491 stat
.gather0
.pri_filter
= pri_filter
;
492 stat
.gather0
.client_enb
= !!client0
;
493 stat
.gather0
.pri_event
= pri_event
;
494 stat
.gather0
.event
= event
;
496 stat
.gather1
.client
= client1
? client1
->id
: 0;
497 stat
.gather1
.pri_filter
= pri_filter
;
498 stat
.gather1
.client_enb
= !!client1
;
499 stat
.gather1
.pri_event
= pri_event
;
500 stat
.gather1
.event
= event
;
502 stat
.sample_time_usec
= MC_STAT_SAMPLE_TIME_USEC
;
505 tegra20_mc_stat_gather(&stat
);
507 *result0
= stat
.gather0
.result
;
508 *result1
= stat
.gather1
.result
;
511 static void tegra20_mc_collect_stats(const struct tegra_mc
*mc
,
512 struct tegra20_mc_client_stat
*stats
)
514 const struct tegra_mc_client
*client0
, *client1
;
517 /* collect memory controller utilization percent for each client */
518 for (i
= 0; i
< mc
->soc
->num_clients
; i
+= 2) {
519 client0
= &mc
->soc
->clients
[i
];
520 client1
= &mc
->soc
->clients
[i
+ 1];
522 if (i
+ 1 == mc
->soc
->num_clients
)
525 tegra20_mc_stat_events(mc
, client0
, client1
,
526 MC_STAT_CONTROL_FILTER_PRI_DISABLE
,
527 MC_STAT_CONTROL_PRI_EVENT_HP
,
528 MC_STAT_CONTROL_EVENT_QUALIFIED
,
529 &stats
[i
+ 0].events
,
530 &stats
[i
+ 1].events
);
533 /* collect more info from active clients */
534 for (i
= 0; i
< mc
->soc
->num_clients
; i
++) {
535 unsigned int clienta
, clientb
= mc
->soc
->num_clients
;
537 for (client0
= NULL
; i
< mc
->soc
->num_clients
; i
++) {
538 if (stats
[i
].events
) {
539 client0
= &mc
->soc
->clients
[i
];
545 for (client1
= NULL
; i
< mc
->soc
->num_clients
; i
++) {
546 if (stats
[i
].events
) {
547 client1
= &mc
->soc
->clients
[i
];
553 if (!client0
&& !client1
)
556 tegra20_mc_stat_events(mc
, client0
, client1
,
557 MC_STAT_CONTROL_FILTER_PRI_YES
,
558 MC_STAT_CONTROL_PRI_EVENT_HP
,
559 MC_STAT_CONTROL_EVENT_QUALIFIED
,
560 &stats
[clienta
].arb_high_prio
,
561 &stats
[clientb
].arb_high_prio
);
563 tegra20_mc_stat_events(mc
, client0
, client1
,
564 MC_STAT_CONTROL_FILTER_PRI_YES
,
565 MC_STAT_CONTROL_PRI_EVENT_TM
,
566 MC_STAT_CONTROL_EVENT_QUALIFIED
,
567 &stats
[clienta
].arb_timeout
,
568 &stats
[clientb
].arb_timeout
);
570 tegra20_mc_stat_events(mc
, client0
, client1
,
571 MC_STAT_CONTROL_FILTER_PRI_YES
,
572 MC_STAT_CONTROL_PRI_EVENT_BW
,
573 MC_STAT_CONTROL_EVENT_QUALIFIED
,
574 &stats
[clienta
].arb_bandwidth
,
575 &stats
[clientb
].arb_bandwidth
);
577 tegra20_mc_stat_events(mc
, client0
, client1
,
578 MC_STAT_CONTROL_FILTER_PRI_DISABLE
,
579 MC_STAT_CONTROL_PRI_EVENT_HP
,
580 MC_STAT_CONTROL_EVENT_RD_WR_CHANGE
,
581 &stats
[clienta
].rd_wr_change
,
582 &stats
[clientb
].rd_wr_change
);
584 tegra20_mc_stat_events(mc
, client0
, client1
,
585 MC_STAT_CONTROL_FILTER_PRI_DISABLE
,
586 MC_STAT_CONTROL_PRI_EVENT_HP
,
587 MC_STAT_CONTROL_EVENT_SUCCESSIVE
,
588 &stats
[clienta
].successive
,
589 &stats
[clientb
].successive
);
591 tegra20_mc_stat_events(mc
, client0
, client1
,
592 MC_STAT_CONTROL_FILTER_PRI_DISABLE
,
593 MC_STAT_CONTROL_PRI_EVENT_HP
,
594 MC_STAT_CONTROL_EVENT_PAGE_MISS
,
595 &stats
[clienta
].page_miss
,
596 &stats
[clientb
].page_miss
);
600 static void tegra20_mc_printf_percents(struct seq_file
*s
,
602 unsigned int percents_fx
)
604 char percents_str
[8];
606 snprintf(percents_str
, ARRAY_SIZE(percents_str
), "%3u.%02u%%",
607 percents_fx
/ MC_FX_FRAC_SCALE
, percents_fx
% MC_FX_FRAC_SCALE
);
609 seq_printf(s
, fmt
, percents_str
);
612 static int tegra20_mc_stats_show(struct seq_file
*s
, void *unused
)
614 const struct tegra_mc
*mc
= dev_get_drvdata(s
->private);
615 struct tegra20_mc_client_stat
*stats
;
618 stats
= kcalloc(mc
->soc
->num_clients
+ 1, sizeof(*stats
), GFP_KERNEL
);
622 mutex_lock(&tegra20_mc_stat_lock
);
624 tegra20_mc_collect_stats(mc
, stats
);
626 mutex_unlock(&tegra20_mc_stat_lock
);
628 seq_puts(s
, "Memory client Events Timeout High priority Bandwidth ARB RW change Successive Page miss\n");
629 seq_puts(s
, "-----------------------------------------------------------------------------------------------------\n");
631 for (i
= 0; i
< mc
->soc
->num_clients
; i
++) {
632 seq_printf(s
, "%-14s ", mc
->soc
->clients
[i
].name
);
634 /* An event is generated when client performs R/W request. */
635 tegra20_mc_printf_percents(s
, "%-9s", stats
[i
].events
);
638 * An event is generated based on the timeout (TM) signal
639 * accompanying a request for arbitration.
641 tegra20_mc_printf_percents(s
, "%-10s", stats
[i
].arb_timeout
);
644 * An event is generated based on the high-priority (HP) signal
645 * accompanying a request for arbitration.
647 tegra20_mc_printf_percents(s
, "%-16s", stats
[i
].arb_high_prio
);
650 * An event is generated based on the bandwidth (BW) signal
651 * accompanying a request for arbitration.
653 tegra20_mc_printf_percents(s
, "%-16s", stats
[i
].arb_bandwidth
);
656 * An event is generated when the memory controller switches
657 * between making a read request to making a write request.
659 tegra20_mc_printf_percents(s
, "%-12s", stats
[i
].rd_wr_change
);
662 * An even generated when the chosen client has wins arbitration
663 * when it was also the winner at the previous request. If a
664 * client makes N requests in a row that are honored, SUCCESSIVE
665 * will be counted (N-1) times. Large values for this event
666 * imply that if we were patient enough, all of those requests
667 * could have been coalesced.
669 tegra20_mc_printf_percents(s
, "%-13s", stats
[i
].successive
);
672 * An event is generated when the memory controller detects a
673 * page miss for the current request.
675 tegra20_mc_printf_percents(s
, "%-12s\n", stats
[i
].page_miss
);
683 static int tegra20_mc_probe(struct tegra_mc
*mc
)
685 debugfs_create_devm_seqfile(mc
->dev
, "stats", mc
->debugfs
.root
,
686 tegra20_mc_stats_show
);
691 static irqreturn_t
tegra20_mc_handle_irq(int irq
, void *data
)
693 struct tegra_mc
*mc
= data
;
694 unsigned long status
;
697 /* mask all interrupts to avoid flooding */
698 status
= mc_readl(mc
, MC_INTSTATUS
) & mc
->soc
->intmask
;
702 for_each_set_bit(bit
, &status
, 32) {
703 const char *error
= tegra_mc_status_names
[bit
];
704 const char *direction
= "read", *secure
= "";
705 const char *client
, *desc
;
711 case MC_INT_DECERR_EMEM
:
712 reg
= MC_DECERR_EMEM_OTHERS_STATUS
;
713 value
= mc_readl(mc
, reg
);
715 id
= value
& mc
->soc
->client_id_mask
;
716 desc
= tegra_mc_error_names
[2];
722 case MC_INT_INVALID_GART_PAGE
:
723 reg
= MC_GART_ERROR_REQ
;
724 value
= mc_readl(mc
, reg
);
726 id
= (value
>> 1) & mc
->soc
->client_id_mask
;
727 desc
= tegra_mc_error_names
[2];
733 case MC_INT_SECURITY_VIOLATION
:
734 reg
= MC_SECURITY_VIOLATION_STATUS
;
735 value
= mc_readl(mc
, reg
);
737 id
= value
& mc
->soc
->client_id_mask
;
738 type
= (value
& BIT(30)) ? 4 : 3;
739 desc
= tegra_mc_error_names
[type
];
750 client
= mc
->soc
->clients
[id
].name
;
751 addr
= mc_readl(mc
, reg
+ sizeof(u32
));
753 dev_err_ratelimited(mc
->dev
, "%s: %s%s @%pa: %s (%s)\n",
754 client
, secure
, direction
, &addr
, error
,
758 /* clear interrupts */
759 mc_writel(mc
, status
, MC_INTSTATUS
);
764 static const struct tegra_mc_ops tegra20_mc_ops
= {
765 .probe
= tegra20_mc_probe
,
766 .handle_irq
= tegra20_mc_handle_irq
,
769 const struct tegra_mc_soc tegra20_mc_soc
= {
770 .clients
= tegra20_mc_clients
,
771 .num_clients
= ARRAY_SIZE(tegra20_mc_clients
),
772 .num_address_bits
= 32,
773 .client_id_mask
= 0x3f,
774 .intmask
= MC_INT_SECURITY_VIOLATION
| MC_INT_INVALID_GART_PAGE
|
776 .reset_ops
= &tegra20_mc_reset_ops
,
777 .resets
= tegra20_mc_resets
,
778 .num_resets
= ARRAY_SIZE(tegra20_mc_resets
),
779 .icc_ops
= &tegra20_mc_icc_ops
,
780 .ops
= &tegra20_mc_ops
,