ARM: tegra: mc: Make error handling make more sense
[linux-3.10.git] / arch / arm / mach-tegra / mcerr-t14.c
1 /*
2  * arch/arm/mach-tegra/mcerr-t14.c
3  *
4  * Tegra 14x SoC-specific mcerr code.
5  *
6  * Copyright (c) 2012-2013, NVIDIA Corporation. All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22
23 #include "mcerr.h"
24
25 #define dummy_client    client("dummy")
26
27 struct mc_client mc_clients[] = {
28         client("ptc"),
29         client("display0_wina"),        client("display1_wina"),
30         client("display0_winb"),        client("display1_winb"),
31         client("display0_winc"),        client("display1_winc"),
32         dummy_client,                   dummy_client,
33         client("epp"),
34         client("gr2d_pat"), /* 10 */    client("gr2d_src"),
35         dummy_client,                   dummy_client,
36         dummy_client,                   client("avp"),
37         client("display0_cursor"),      client("display1_cursor"),
38         client("gr3d_fdc0"),            client("gr3d_fdc1"),
39         client("gr2d_dst"), /* 20 */
40         client("hda"),
41         client("host1x_dma"),           client("host1x_generic"),
42         client("gr3d0_idx"),            dummy_client,
43         dummy_client,                   dummy_client,
44         client("msenc"),
45         client("ahb_dma"),              client("ahb_slave_r"), /* 30 */
46         dummy_client,                   client("gr3d0_tex"),
47         dummy_client,
48         client("vde_bsev"),             client("vde_mbe"),
49         client("vde_mce"),              client("vde_tpe"),
50         client("cpu_lp"),               client("cpu"),
51         client("epp_u"), /* 40 */
52         client("epp_v"),
53         client("epp_y"),
54         client("msenc"),
55         client("vi_sb"),                client("vi_u"),
56         client("vi_v"),                 client("vi_y"),
57         client("gr2d_dst"),
58         dummy_client,
59         client("avp"), /* 50 */
60         client("gr3d_fdc0"),            client("gr3d_fdc1"),
61         client("hda"),
62         client("host1x"),
63         client("isp"),
64         client("cpu_lp"),               client("cpu"),
65         dummy_client,
66         client("ahb_dma"),              client("ahb_slave_w"), /* 60 */
67         dummy_client,
68         client("vde_bsev"),             client("vde_dbg"),
69         client("vde_mbe"),              client("vde_tpm"),
70         dummy_client,                   dummy_client,
71         client("ve_ispra"),             dummy_client,
72         client("ve_ispwa"), /* 70 */    client("ve_ispwb"),
73         dummy_client,                   dummy_client,
74         dummy_client,                   dummy_client,
75         dummy_client,                   dummy_client,
76         dummy_client,                   dummy_client,
77         dummy_client, /* 80 */          dummy_client,
78         client("emucif"),               client("emucif"),
79         client("tsec"),                 client("tsec"),
80         client("viw"),                  client("bbcr"),
81         client("bbcw"),                 client("bbcllr"),
82         client("disp_t"), /* 90 */      dummy_client,
83         client("disp_d"),
84 };
85
86 int mc_client_last = ARRAY_SIZE(mc_clients) - 1;
87
88 static void mcerr_t14x_info_update(struct mc_client *c, u32 stat)
89 {
90         if (stat & MC_INT_DECERR_EMEM)
91                 c->intr_counts[0]++;
92         if (stat & MC_INT_SECURITY_VIOLATION)
93                 c->intr_counts[1]++;
94         if (stat & MC_INT_INVALID_SMMU_PAGE)
95                 c->intr_counts[2]++;
96         if (stat & MC_INT_DECERR_VPR)
97                 c->intr_counts[3]++;
98         if (stat & MC_INT_SECERR_SEC)
99                 c->intr_counts[4]++;
100         if (stat & MC_INT_BBC_PRIVATE_MEM_VIOLATION)
101                 c->intr_counts[5]++;
102         if (stat & MC_INT_DECERR_BBC)
103                 c->intr_counts[6]++;
104
105         if (stat & ~MC_INT_EN_MASK)
106                 c->intr_counts[7]++;
107 }
108
109 static int mcerr_t14x_debugfs_show(struct seq_file *s, void *v)
110 {
111         int i, j;
112         int do_print;
113         const char *fmt = "%-18s %-9u %-9u %-9u %-10u %-10u %-9u %-9u %-9u\n";
114
115         seq_printf(s, "%-18s %-9s %-9s %-9s %-10s %-10s %-9s %-9s %-9s\n",
116                    "client", "decerr", "secerr", "smmuerr",
117                    "decerr-VPR", "secerr-SEC", "priv-bbc", "decerr-bbc",
118                    "unknown");
119         for (i = 0; i < ARRAY_SIZE(mc_clients); i++) {
120                 do_print = 0;
121                 if (strcmp(mc_clients[i].name, "dummy") == 0)
122                         continue;
123                 /* Only print clients who actually have errors. */
124                 for (j = 0; j < INTR_COUNT; j++) {
125                         if (mc_clients[i].intr_counts[j]) {
126                                 do_print = 1;
127                                 break;
128                         }
129                 }
130                 if (do_print)
131                         seq_printf(s, fmt,
132                                    mc_clients[i].name,
133                                    mc_clients[i].intr_counts[0],
134                                    mc_clients[i].intr_counts[1],
135                                    mc_clients[i].intr_counts[2],
136                                    mc_clients[i].intr_counts[3],
137                                    mc_clients[i].intr_counts[4],
138                                    mc_clients[i].intr_counts[5],
139                                    mc_clients[i].intr_counts[6],
140                                    mc_clients[i].intr_counts[7]);
141         }
142         return 0;
143 }
144
145 /*
146  * Set up chip specific functions and data for handling this particular chip's
147  * error decoding and logging.
148  */
149 void mcerr_chip_specific_setup(struct mcerr_chip_specific *spec)
150 {
151         spec->mcerr_info_update = mcerr_t14x_info_update;
152         spec->mcerr_debugfs_show = mcerr_t14x_debugfs_show;
153         spec->nr_clients = ARRAY_SIZE(mc_clients);
154         return;
155 }