179c0b836d9f9b3fd6cdb8e6a24b3f2a90868b18
[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, 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 static char unknown_buf[30];
28
29 struct mc_client mc_clients[] = {
30         client("ptc"),
31         client("display0_wina"),        client("display1_wina"),
32         client("display0_winb"),        client("display1_winb"),
33         client("display0_winc"),        client("display1_winc"),
34         dummy_client,                   dummy_client,
35         client("epp"),
36         client("gr2d_pat"), /* 10 */    client("gr2d_src"),
37         dummy_client,                   dummy_client,
38         dummy_client,                   client("avp"),
39         client("display0_cursor"),      client("display1_cursor"),
40         client("gr3d_fdc0"),            client("gr3d_fdc1"),
41         client("gr2d_dst"), /* 20 */
42         client("hda"),
43         client("host1x_dma"),           client("host1x_generic"),
44         client("gr3d0_idx"),            dummy_client,
45         dummy_client,                   dummy_client,
46         client("msenc"),
47         client("ahb_dma"),              client("ahb_slave"), /* 30 */
48         dummy_client,                   client("gr3d0_tex"),
49         dummy_client,
50         client("vde_bsev"),             client("vde_mbe"),
51         client("vde_mce"),              client("vde_tpe"),
52         client("cpu_lp"),               client("cpu"),
53         client("epp_u"), /* 40 */
54         client("epp_v"),
55         client("epp_y"),
56         client("msenc"),
57         client("vi_sb"),                client("vi_u"),
58         client("vi_v"),                 client("vi_y"),
59         client("gr2d_dst"),
60         dummy_client,
61         client("avp"), /* 50 */
62         client("gr3d_fdc0"),            client("gr3d_fdc1"),
63         client("hda"),
64         client("host1x"),
65         client("isp"),
66         client("cpu_lp"),               client("cpu"),
67         dummy_client,
68         client("ahb_dma"),              client("ahb_slave"), /* 60 */
69         dummy_client,
70         client("vde_bsev"),             client("vde_dbg"),
71         client("vde_mbe"),              client("vde_tpm"),
72         dummy_client,                   dummy_client,
73         client("ve_ispra"),             dummy_client,
74         client("ve_ispwa"), /* 70 */    client("ve_ispwb"),
75         dummy_client,                   dummy_client,
76         dummy_client,                   dummy_client,
77         dummy_client,                   dummy_client,
78         dummy_client,                   dummy_client,
79         dummy_client, /* 80 */          dummy_client,
80         client("emucif"),               client("emucif"),
81         client("tsec"),                 client("tsec"),
82         client("viw"),                  client("bbcr"),
83         client("bbcw"),                 client("bbcllr"),
84         client("disp_t"), /* 90 */      dummy_client,
85         client("disp_d"),
86 };
87
88 int mc_client_last = ARRAY_SIZE(mc_clients) - 1;
89
90 static const char *mcerr_t14x_info(u32 stat)
91 {
92         if (stat & MC_INT_DECERR_EMEM)
93                 return "MC_DECERR";
94         else if (stat & MC_INT_SECURITY_VIOLATION)
95                 return "MC_SECURITY_ERR";
96         else if (stat & MC_INT_INVALID_SMMU_PAGE)
97                 return "MC_SMMU_ERR";
98         else if (stat & MC_INT_DECERR_VPR)
99                 return "MC_DECERR_VPR";
100         else if (stat & MC_INT_SECERR_SEC)
101                 return "MC_SECERR_SEC";
102         else if (stat & MC_INT_BBC_PRIVATE_MEM_VIOLATION)
103                 return "MC_BBC_PRIVATE_MEM_VIOLATION";
104         else if (stat & MC_INT_DECERR_BBC)
105                 return "MC_DECERR_BBC";
106
107         /* Otherwise we have an unknown type... */
108         snprintf(unknown_buf, 30, "unknown - 0x%04x", stat);
109         return unknown_buf;
110 }
111
112 static void mcerr_t14x_info_update(struct mc_client *c, u32 stat)
113 {
114         if (stat & MC_INT_DECERR_EMEM)
115                 c->intr_counts[0]++;
116         else if (stat & MC_INT_SECURITY_VIOLATION)
117                 c->intr_counts[1]++;
118         else if (stat & MC_INT_INVALID_SMMU_PAGE)
119                 c->intr_counts[2]++;
120         else if (stat & MC_INT_DECERR_VPR)
121                 c->intr_counts[3]++;
122         else if (stat & MC_INT_SECERR_SEC)
123                 c->intr_counts[4]++;
124         else if (stat & MC_INT_BBC_PRIVATE_MEM_VIOLATION)
125                 c->intr_counts[5]++;
126         else if (stat & MC_INT_DECERR_BBC)
127                 c->intr_counts[6]++;
128         else
129                 c->intr_counts[7]++;
130 }
131
132 static int mcerr_t14x_debugfs_show(struct seq_file *s, void *v)
133 {
134         int i, j;
135         int do_print;
136         const char *fmt = "%-18s %-9u %-9u %-9u %-10u %-10u %-9u %-9u %-9u\n";
137
138         seq_printf(s, "%-18s %-9s %-9s %-9s %-10s %-10s %-9s %-9s %-9s\n",
139                    "client", "decerr", "secerr", "smmuerr",
140                    "decerr-VPR", "secerr-SEC", "priv-bbc", "decerr-bbc",
141                    "unknown");
142         for (i = 0; i < ARRAY_SIZE(mc_clients); i++) {
143                 do_print = 0;
144                 if (strcmp(mc_clients[i].name, "dummy") == 0)
145                         continue;
146                 /* Only print clients who actually have errors. */
147                 for (j = 0; j < INTR_COUNT; j++) {
148                         if (mc_clients[i].intr_counts[j]) {
149                                 do_print = 1;
150                                 break;
151                         }
152                 }
153                 if (do_print)
154                         seq_printf(s, fmt,
155                                    mc_clients[i].name,
156                                    mc_clients[i].intr_counts[0],
157                                    mc_clients[i].intr_counts[1],
158                                    mc_clients[i].intr_counts[2],
159                                    mc_clients[i].intr_counts[3],
160                                    mc_clients[i].intr_counts[4],
161                                    mc_clients[i].intr_counts[5],
162                                    mc_clients[i].intr_counts[6],
163                                    mc_clients[i].intr_counts[7]);
164         }
165         return 0;
166 }
167
168 /*
169  * Set up chip specific functions and data for handling this particular chip's
170  * error decoding and logging.
171  */
172 void mcerr_chip_specific_setup(struct mcerr_chip_specific *spec)
173 {
174         spec->mcerr_info = mcerr_t14x_info;
175         spec->mcerr_info_update = mcerr_t14x_info_update;
176         spec->mcerr_debugfs_show = mcerr_t14x_debugfs_show;
177         spec->nr_clients = ARRAY_SIZE(mc_clients);
178         return;
179 }