xref: /linux/drivers/soc/tegra/cbb/tegra234-cbb.c (revision f1aa30a4b23d905dd39944cdffdf68c8cc3e28a9)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2021-2025, NVIDIA CORPORATION. All rights reserved
4  *
5  * The driver handles Error's from Control Backbone(CBB) version 2.0.
6  * generated due to illegal accesses. The driver prints debug information
7  * about failed transaction on receiving interrupt from Error Notifier.
8  * Error types supported by CBB2.0 are:
9  *   UNSUPPORTED_ERR, PWRDOWN_ERR, TIMEOUT_ERR, FIREWALL_ERR, DECODE_ERR,
10  *   TARGET_ERR
11  */
12 
13 #include <linux/acpi.h>
14 #include <linux/clk.h>
15 #include <linux/cpufeature.h>
16 #include <linux/debugfs.h>
17 #include <linux/module.h>
18 #include <linux/of.h>
19 #include <linux/platform_device.h>
20 #include <linux/device.h>
21 #include <linux/io.h>
22 #include <linux/interrupt.h>
23 #include <linux/ioport.h>
24 #include <soc/tegra/fuse.h>
25 #include <soc/tegra/tegra-cbb.h>
26 
27 #define FABRIC_EN_CFG_INTERRUPT_ENABLE_0_0	0x0
28 #define FABRIC_EN_CFG_STATUS_0_0		0x40
29 #define FABRIC_EN_CFG_ADDR_INDEX_0_0		0x60
30 #define FABRIC_EN_CFG_ADDR_LOW_0		0x80
31 #define FABRIC_EN_CFG_ADDR_HI_0			0x84
32 
33 #define FABRIC_EN_CFG_TARGET_NODE_ADDR_INDEX_0_0 0x100
34 #define FABRIC_EN_CFG_TARGET_NODE_ADDR_LOW_0    0x140
35 #define FABRIC_EN_CFG_TARGET_NODE_ADDR_HI_0     0x144
36 
37 #define FABRIC_MN_INITIATOR_ERR_EN_0		0x200
38 #define FABRIC_MN_INITIATOR_ERR_FORCE_0		0x204
39 #define FABRIC_MN_INITIATOR_ERR_STATUS_0	0x208
40 #define FABRIC_MN_INITIATOR_ERR_OVERFLOW_STATUS_0 0x20c
41 
42 #define FABRIC_MN_INITIATOR_LOG_ERR_STATUS_0	0x300
43 #define FABRIC_MN_INITIATOR_LOG_ADDR_LOW_0	0x304
44 #define FABRIC_MN_INITIATOR_LOG_ADDR_HIGH_0	0x308
45 #define FABRIC_MN_INITIATOR_LOG_ATTRIBUTES0_0	0x30c
46 #define FABRIC_MN_INITIATOR_LOG_ATTRIBUTES1_0	0x310
47 #define FABRIC_MN_INITIATOR_LOG_ATTRIBUTES2_0	0x314
48 #define FABRIC_MN_INITIATOR_LOG_USER_BITS0_0	0x318
49 
50 #define AXI_SLV_TIMEOUT_STATUS_0_0		0x8
51 #define APB_BLOCK_TMO_STATUS_0			0xc00
52 #define APB_BLOCK_NUM_TMO_OFFSET		0x20
53 
54 #define FAB_EM_EL_MSTRID		GENMASK(29, 24)
55 #define FAB_EM_EL_VQC			GENMASK(17, 16)
56 #define FAB_EM_EL_GRPSEC		GENMASK(14, 8)
57 #define FAB_EM_EL_FALCONSEC		GENMASK(1, 0)
58 
59 #define FAB_EM_EL_FABID			GENMASK(20, 16)
60 #define FAB_EM_EL_TARGETID		GENMASK(7, 0)
61 
62 #define FAB_EM_EL_ACCESSID		GENMASK(7, 0)
63 
64 #define FAB_EM_EL_AXCACHE		GENMASK(27, 24)
65 #define FAB_EM_EL_AXPROT		GENMASK(22, 20)
66 #define FAB_EM_EL_BURSTLENGTH		GENMASK(19, 12)
67 #define FAB_EM_EL_BURSTTYPE		GENMASK(9, 8)
68 #define FAB_EM_EL_BEATSIZE		GENMASK(6, 4)
69 #define FAB_EM_EL_ACCESSTYPE		GENMASK(0, 0)
70 
71 #define USRBITS_MSTR_ID			GENMASK(29, 24)
72 
73 #define REQ_SOCKET_ID			GENMASK(27, 24)
74 
75 #define CCPLEX_MSTRID			0x1
76 #define FIREWALL_APERTURE_SZ		0x10000
77 /* Write firewall check enable */
78 #define WEN				0x20000
79 
80 enum tegra234_cbb_fabric_ids {
81 	T234_CBB_FABRIC_ID,
82 	T234_SCE_FABRIC_ID,
83 	T234_RCE_FABRIC_ID,
84 	T234_DCE_FABRIC_ID,
85 	T234_AON_FABRIC_ID,
86 	T234_PSC_FABRIC_ID,
87 	T234_BPMP_FABRIC_ID,
88 	T234_FSI_FABRIC_ID,
89 	T234_MAX_FABRIC_ID,
90 };
91 
92 enum tegra238_cbb_fabric_ids {
93 	T238_CBB_FABRIC_ID  = 0,
94 	T238_AON_FABRIC_ID  = 4,
95 	T238_PSC_FABRIC_ID  = 5,
96 	T238_BPMP_FABRIC_ID = 6,
97 	T238_APE_FABRIC_ID  = 7,
98 	T238_MAX_FABRIC_ID,
99 };
100 
101 enum tegra264_cbb_fabric_ids {
102 	T264_SYSTEM_CBB_FABRIC_ID,
103 	T264_TOP_0_CBB_FABRIC_ID,
104 	T264_VISION_CBB_FABRIC_ID,
105 	T264_DISP_USB_CBB_FABRIC_ID,
106 	T264_UPHY0_CBB_FABRIC_ID,
107 	T264_RSVD0_FABRIC_ID,
108 	T264_RSVD1_FABRIC_ID,
109 	T264_RSVD2_FABRIC_ID,
110 	T264_RSVD3_FABRIC_ID,
111 	T264_RSVD4_FABRIC_ID,
112 	T264_RSVD5_FABRIC_ID,
113 	T264_AON_FABRIC_ID,
114 	T264_PSC_FABRIC_ID,
115 	T264_OESP_FABRIC_ID,
116 	T264_APE_FABRIC_ID,
117 	T264_BPMP_FABRIC_ID,
118 	T264_RCE_0_FABRIC_ID,
119 	T264_RCE_1_FABRIC_ID,
120 	T264_RSVD6_FABRIC_ID,
121 	T264_DCE_FABRIC_ID,
122 	T264_FSI_FABRIC_ID,
123 	T264_ISC_FABRIC_ID,
124 	T264_SB_FABRIC_ID,
125 	T264_ISC_CPU_FABRIC_ID,
126 	T264_RSVD7_FABRIC_ID,
127 };
128 
129 enum t254_cbb_fabric_ids {
130 	T254_DCE_FABRIC_ID             = 19,
131 	T254_DISP_CLUSTER_FABRIC_ID    = 25,
132 	T254_C2C_FABRIC_ID             = 26,
133 	T254_GPU_FABRIC_ID             = 27,
134 	T254_DISP_CLUSTER_1_FABRIC_ID  = 28,
135 	T254_MAX_FABRIC_ID,
136 };
137 
138 struct tegra234_target_lookup {
139 	const char *name;
140 	unsigned int offset;
141 };
142 
143 struct tegra234_fabric_lookup {
144 	const char *name;
145 	bool is_lookup;
146 	const struct tegra234_target_lookup *target_map;
147 	const int max_targets;
148 };
149 
150 struct tegra234_cbb_fabric {
151 	int fab_id;
152 	phys_addr_t off_mask_erd;
153 	phys_addr_t firewall_base;
154 	unsigned int firewall_ctl;
155 	unsigned int firewall_wr_ctl;
156 	const char * const *initiator_id;
157 	unsigned int notifier_offset;
158 	const struct tegra_cbb_error *errors;
159 	const int max_errors;
160 	const struct tegra234_fabric_lookup *fab_list;
161 	const u32 err_intr_enbl;
162 	const u32 err_status_clr;
163 };
164 
165 struct tegra234_cbb {
166 	struct tegra_cbb base;
167 
168 	const struct tegra234_cbb_fabric *fabric;
169 	struct resource *res;
170 	void __iomem *regs;
171 
172 	int num_intr;
173 	int sec_irq;
174 
175 	/* record */
176 	void __iomem *mon;
177 	unsigned int type;
178 	u32 mask;
179 	u64 access;
180 	u32 mn_attr0;
181 	u32 mn_attr1;
182 	u32 mn_attr2;
183 	u32 mn_user_bits;
184 };
185 
186 static inline struct tegra234_cbb *to_tegra234_cbb(struct tegra_cbb *cbb)
187 {
188 	return container_of(cbb, struct tegra234_cbb, base);
189 }
190 
191 static LIST_HEAD(cbb_list);
192 static DEFINE_SPINLOCK(cbb_lock);
193 
194 static bool
195 tegra234_cbb_write_access_allowed(struct platform_device *pdev, struct tegra234_cbb *cbb)
196 {
197 	u32 val;
198 
199 	if (!cbb->fabric->firewall_base ||
200 	    !cbb->fabric->firewall_ctl ||
201 	    !cbb->fabric->firewall_wr_ctl) {
202 		dev_info(&pdev->dev, "SoC data missing for firewall\n");
203 		return false;
204 	}
205 
206 	if ((cbb->fabric->firewall_ctl > FIREWALL_APERTURE_SZ) ||
207 	    (cbb->fabric->firewall_wr_ctl > FIREWALL_APERTURE_SZ)) {
208 		dev_err(&pdev->dev, "wrong firewall offset value\n");
209 		return false;
210 	}
211 
212 	val = readl(cbb->regs + cbb->fabric->firewall_base + cbb->fabric->firewall_ctl);
213 	/*
214 	 * If the firewall check feature for allowing or blocking the
215 	 * write accesses through the firewall of a fabric is disabled
216 	 * then CCPLEX can write to the registers of that fabric.
217 	 */
218 	if (!(val & WEN))
219 		return true;
220 
221 	/*
222 	 * If the firewall check is enabled then check whether CCPLEX
223 	 * has write access to the fabric's error notifier registers
224 	 */
225 	val = readl(cbb->regs + cbb->fabric->firewall_base + cbb->fabric->firewall_wr_ctl);
226 	if (val & (BIT(CCPLEX_MSTRID)))
227 		return true;
228 
229 	return false;
230 }
231 
232 static void tegra234_cbb_fault_enable(struct tegra_cbb *cbb)
233 {
234 	struct tegra234_cbb *priv = to_tegra234_cbb(cbb);
235 	void __iomem *addr;
236 
237 	addr = priv->regs + priv->fabric->notifier_offset;
238 	writel(priv->fabric->err_intr_enbl, addr + FABRIC_EN_CFG_INTERRUPT_ENABLE_0_0);
239 	dsb(sy);
240 }
241 
242 static void tegra234_cbb_error_clear(struct tegra_cbb *cbb)
243 {
244 	struct tegra234_cbb *priv = to_tegra234_cbb(cbb);
245 
246 	writel(0, priv->mon + FABRIC_MN_INITIATOR_ERR_FORCE_0);
247 
248 	writel(priv->fabric->err_status_clr, priv->mon + FABRIC_MN_INITIATOR_ERR_STATUS_0);
249 	dsb(sy);
250 }
251 
252 static u32 tegra234_cbb_get_status(struct tegra_cbb *cbb)
253 {
254 	struct tegra234_cbb *priv = to_tegra234_cbb(cbb);
255 	void __iomem *addr;
256 	u32 value;
257 
258 	addr = priv->regs + priv->fabric->notifier_offset;
259 	value = readl(addr + FABRIC_EN_CFG_STATUS_0_0);
260 	dsb(sy);
261 
262 	return value;
263 }
264 
265 static void tegra234_cbb_mask_serror(struct tegra234_cbb *cbb)
266 {
267 	writel(0x1, cbb->regs + cbb->fabric->off_mask_erd);
268 	dsb(sy);
269 }
270 
271 static u32 tegra234_cbb_get_tmo_slv(void __iomem *addr)
272 {
273 	u32 timeout;
274 
275 	timeout = readl(addr);
276 	return timeout;
277 }
278 
279 static void tegra234_cbb_tmo_slv(struct seq_file *file, const char *target, void __iomem *addr,
280 				 u32 status)
281 {
282 	tegra_cbb_print_err(file, "\t  %s : %#x\n", target, status);
283 }
284 
285 static void tegra234_cbb_lookup_apbslv(struct seq_file *file, const char *target,
286 				       void __iomem *base)
287 {
288 	unsigned int block = 0;
289 	void __iomem *addr;
290 	char name[64];
291 	u32 status;
292 
293 	status = tegra234_cbb_get_tmo_slv(base);
294 	if (status)
295 		tegra_cbb_print_err(file, "\t  %s_BLOCK_TMO_STATUS : %#x\n", target, status);
296 
297 	while (status) {
298 		if (status & BIT(0)) {
299 			u32 timeout, clients, client = 0;
300 
301 			addr = base + APB_BLOCK_NUM_TMO_OFFSET + (block * 4);
302 			timeout = tegra234_cbb_get_tmo_slv(addr);
303 			clients = timeout;
304 
305 			while (timeout) {
306 				if (timeout & BIT(0)) {
307 					if (clients != 0xffffffff)
308 						clients &= BIT(client);
309 
310 					sprintf(name, "%s_BLOCK%d_TMO", target, block);
311 
312 					tegra234_cbb_tmo_slv(file, name, addr, clients);
313 				}
314 
315 				timeout >>= 1;
316 				client++;
317 			}
318 		}
319 
320 		status >>= 1;
321 		block++;
322 	}
323 }
324 
325 static struct tegra234_cbb *tegra234_cbb_get_fabric(u8 fab_id)
326 {
327 	struct tegra_cbb *entry;
328 
329 	list_for_each_entry(entry, &cbb_list, node) {
330 		struct tegra234_cbb *priv = to_tegra234_cbb(entry);
331 
332 		if (priv->fabric->fab_id == fab_id)
333 			return priv;
334 	}
335 
336 	return NULL;
337 }
338 
339 static void tegra234_sw_lookup_target_timeout(struct seq_file *file, struct tegra234_cbb *cbb,
340 					      u8 target_id, u8 fab_id)
341 {
342 	const struct tegra234_target_lookup *map = cbb->fabric->fab_list[fab_id].target_map;
343 	struct tegra234_cbb *target_cbb = NULL;
344 	void __iomem *addr;
345 
346 	if (fab_id == cbb->fabric->fab_id)
347 		target_cbb = cbb;
348 	else
349 		target_cbb = tegra234_cbb_get_fabric(fab_id);
350 
351 	if (!target_cbb) {
352 		dev_err(cbb->base.dev, "could not find fabric for fab_id:%d\n", fab_id);
353 		return;
354 	}
355 
356 	if (target_id >= cbb->fabric->fab_list[fab_id].max_targets) {
357 		tegra_cbb_print_err(file, "\t  Invalid target_id:%d\n", target_id);
358 		return;
359 	}
360 
361 	/*
362 	 * 1) Get target node name and address mapping using target_id.
363 	 * 2) Check if the timed out target node is APB or AXI.
364 	 * 3) If AXI, then print timeout register and reset axi target
365 	 *    using <FABRIC>_SN_<>_SLV_TIMEOUT_STATUS_0_0 register.
366 	 * 4) If APB, then perform an additional lookup to find the client
367 	 *    which timed out.
368 	 *	a) Get block number from the index of set bit in
369 	 *	   <FABRIC>_SN_AXI2APB_<>_BLOCK_TMO_STATUS_0 register.
370 	 *	b) Get address of register respective to block number i.e.
371 	 *	   <FABRIC>_SN_AXI2APB_<>_BLOCK<index-set-bit>_TMO_0.
372 	 *	c) Read the register in above step to get client_id which
373 	 *	   timed out as per the set bits.
374 	 *      d) Reset the timedout client and print details.
375 	 *	e) Goto step-a till all bits are set.
376 	 */
377 
378 	addr = target_cbb->regs + map[target_id].offset;
379 
380 	if (strstr(map[target_id].name, "AXI2APB")) {
381 		addr += APB_BLOCK_TMO_STATUS_0;
382 
383 		tegra234_cbb_lookup_apbslv(file, map[target_id].name, addr);
384 	} else {
385 		char name[64];
386 		u32 status;
387 
388 		addr += AXI_SLV_TIMEOUT_STATUS_0_0;
389 
390 		status = tegra234_cbb_get_tmo_slv(addr);
391 		if (status) {
392 			sprintf(name, "%s_SLV_TIMEOUT_STATUS", map[target_id].name);
393 			tegra234_cbb_tmo_slv(file, name, addr, status);
394 		}
395 	}
396 }
397 
398 static void tegra234_hw_lookup_target_timeout(struct seq_file *file, struct tegra234_cbb *cbb,
399 					      u8 target_id, u8 fab_id)
400 {
401 	unsigned int notifier = cbb->fabric->notifier_offset;
402 	u32 hi, lo;
403 	u64 addr;
404 
405 	writel(target_id, cbb->regs + notifier + FABRIC_EN_CFG_TARGET_NODE_ADDR_INDEX_0_0);
406 
407 	hi = readl(cbb->regs + notifier + FABRIC_EN_CFG_TARGET_NODE_ADDR_HI_0);
408 	lo = readl(cbb->regs + notifier + FABRIC_EN_CFG_TARGET_NODE_ADDR_LOW_0);
409 
410 	addr = (u64)hi << 32 | lo;
411 
412 	tegra_cbb_print_err(file, "\t  Target Node Addr : %#llx\n", addr);
413 }
414 
415 static void tegra234_cbb_print_error(struct seq_file *file, struct tegra234_cbb *cbb, u32 status,
416 				     u32 overflow)
417 {
418 	unsigned int type = 0;
419 
420 	if (status & (status - 1))
421 		tegra_cbb_print_err(file, "\t  Multiple type of errors reported\n");
422 
423 	while (status) {
424 		if (type >= cbb->fabric->max_errors) {
425 			tegra_cbb_print_err(file, "\t  Wrong type index:%u, status:%u\n",
426 					    type, status);
427 			return;
428 		}
429 
430 		if (status & 0x1)
431 			tegra_cbb_print_err(file, "\t  Error Code\t\t: %s\n",
432 					    cbb->fabric->errors[type].code);
433 
434 		status >>= 1;
435 		type++;
436 	}
437 
438 	type = 0;
439 
440 	while (overflow) {
441 		if (type >= cbb->fabric->max_errors) {
442 			tegra_cbb_print_err(file, "\t  Wrong type index:%u, overflow:%u\n",
443 					    type, overflow);
444 			return;
445 		}
446 
447 		if (overflow & 0x1)
448 			tegra_cbb_print_err(file, "\t  Overflow\t\t: Multiple %s\n",
449 					    cbb->fabric->errors[type].code);
450 
451 		overflow >>= 1;
452 		type++;
453 	}
454 }
455 
456 static void print_errlog_err(struct seq_file *file, struct tegra234_cbb *cbb)
457 {
458 	u8 cache_type, prot_type, burst_length, mstr_id, grpsec, vqc, falconsec, beat_size;
459 	u8 access_type, access_id, requester_socket_id, local_socket_id, target_id, fab_id;
460 	bool is_numa = false;
461 	u8 burst_type;
462 
463 	if (num_possible_nodes() > 1)
464 		is_numa = true;
465 
466 	mstr_id = FIELD_GET(FAB_EM_EL_MSTRID, cbb->mn_user_bits);
467 	vqc = FIELD_GET(FAB_EM_EL_VQC, cbb->mn_user_bits);
468 	grpsec = FIELD_GET(FAB_EM_EL_GRPSEC, cbb->mn_user_bits);
469 	falconsec = FIELD_GET(FAB_EM_EL_FALCONSEC, cbb->mn_user_bits);
470 
471 	/*
472 	 * For SOC with multiple NUMA nodes, print cross socket access
473 	 * errors only if initiator_id is CCPLEX, CPMU or GPU.
474 	 */
475 	if (is_numa) {
476 		local_socket_id = numa_node_id();
477 		requester_socket_id = FIELD_GET(REQ_SOCKET_ID, cbb->mn_attr2);
478 
479 		if (requester_socket_id != local_socket_id) {
480 			if ((mstr_id != 0x1) && (mstr_id != 0x2) && (mstr_id != 0xB))
481 				return;
482 		}
483 	}
484 
485 	fab_id = FIELD_GET(FAB_EM_EL_FABID, cbb->mn_attr2);
486 	target_id = FIELD_GET(FAB_EM_EL_TARGETID, cbb->mn_attr2);
487 
488 	access_id = FIELD_GET(FAB_EM_EL_ACCESSID, cbb->mn_attr1);
489 
490 	cache_type = FIELD_GET(FAB_EM_EL_AXCACHE, cbb->mn_attr0);
491 	prot_type = FIELD_GET(FAB_EM_EL_AXPROT, cbb->mn_attr0);
492 	burst_length = FIELD_GET(FAB_EM_EL_BURSTLENGTH, cbb->mn_attr0);
493 	burst_type = FIELD_GET(FAB_EM_EL_BURSTTYPE, cbb->mn_attr0);
494 	beat_size = FIELD_GET(FAB_EM_EL_BEATSIZE, cbb->mn_attr0);
495 	access_type = FIELD_GET(FAB_EM_EL_ACCESSTYPE, cbb->mn_attr0);
496 
497 	tegra_cbb_print_err(file, "\n");
498 	if (cbb->type < cbb->fabric->max_errors)
499 		tegra_cbb_print_err(file, "\t  Error Code\t\t: %s\n",
500 				    cbb->fabric->errors[cbb->type].code);
501 	else
502 		tegra_cbb_print_err(file, "\t  Wrong type index:%u\n", cbb->type);
503 
504 	tegra_cbb_print_err(file, "\t  Initiator_Id\t\t: %#x\n", mstr_id);
505 	if (cbb->fabric->initiator_id)
506 		tegra_cbb_print_err(file, "\t  Initiator\t\t: %s\n",
507 				    cbb->fabric->initiator_id[mstr_id]);
508 
509 	tegra_cbb_print_err(file, "\t  Address\t\t: %#llx\n", cbb->access);
510 
511 	tegra_cbb_print_cache(file, cache_type);
512 	tegra_cbb_print_prot(file, prot_type);
513 
514 	tegra_cbb_print_err(file, "\t  Access_Type\t\t: %s", (access_type) ? "Write\n" : "Read\n");
515 	tegra_cbb_print_err(file, "\t  Access_ID\t\t: %#x\n", access_id);
516 
517 	if (is_numa) {
518 		tegra_cbb_print_err(file, "\t  Requester_Socket_Id\t: %#x\n",
519 				    requester_socket_id);
520 		tegra_cbb_print_err(file, "\t  Local_Socket_Id\t: %#x\n",
521 				    local_socket_id);
522 		tegra_cbb_print_err(file, "\t  No. of NUMA_NODES\t: %#x\n",
523 				    num_possible_nodes());
524 	}
525 
526 	tegra_cbb_print_err(file, "\t  Fabric\t\t: %s (id:%#x)\n",
527 			    cbb->fabric->fab_list[fab_id].name, fab_id);
528 
529 	if (of_machine_is_compatible("nvidia,tegra264") && fab_id == T264_UPHY0_CBB_FABRIC_ID) {
530 		/*
531 		 * In T264, AON Fabric ID value is incorrectly same as UPHY0 fabric ID.
532 		 * For 'ID = 0x4', we must check for the address which caused the error
533 		 * to find the correct fabric which returned error.
534 		 */
535 		tegra_cbb_print_err(file, "\t  or Fabric\t\t: %s\n",
536 				    cbb->fabric->fab_list[T264_AON_FABRIC_ID].name);
537 		tegra_cbb_print_err(file, "\t  Please use Address to determine correct fabric.\n");
538 	}
539 
540 	tegra_cbb_print_err(file, "\t  Target_Id\t\t: %#x\n", target_id);
541 	tegra_cbb_print_err(file, "\t  Burst_length\t\t: %#x\n", burst_length);
542 	tegra_cbb_print_err(file, "\t  Burst_type\t\t: %#x\n", burst_type);
543 	tegra_cbb_print_err(file, "\t  Beat_size\t\t: %#x\n", beat_size);
544 	tegra_cbb_print_err(file, "\t  VQC\t\t\t: %#x\n", vqc);
545 	tegra_cbb_print_err(file, "\t  GRPSEC\t\t: %#x\n", grpsec);
546 	tegra_cbb_print_err(file, "\t  FALCONSEC\t\t: %#x\n", falconsec);
547 
548 	if (!cbb->fabric->fab_list[fab_id].is_lookup)
549 		return;
550 
551 	/*
552 	 * If is_lookup field is set in fabric_lookup table of soc data, it
553 	 * means that address lookup of target is supported for Timeout errors.
554 	 * If is_lookup is set and the target_map is not populated making
555 	 * max_targets as zero, then it means HW lookup is to be performed.
556 	 */
557 	if (!strcmp(cbb->fabric->errors[cbb->type].code, "TIMEOUT_ERR")) {
558 		if (cbb->fabric->fab_list[fab_id].max_targets)
559 			tegra234_sw_lookup_target_timeout(file, cbb, target_id, fab_id);
560 		else
561 			tegra234_hw_lookup_target_timeout(file, cbb, target_id, fab_id);
562 	}
563 
564 	return;
565 }
566 
567 static int print_errmonX_info(struct seq_file *file, struct tegra234_cbb *cbb)
568 {
569 	u32 overflow, status, error;
570 
571 	status = readl(cbb->mon + FABRIC_MN_INITIATOR_ERR_STATUS_0);
572 	if (!status) {
573 		pr_err("Error Notifier received a spurious notification\n");
574 		return -ENODATA;
575 	}
576 
577 	if (status == 0xffffffff) {
578 		pr_err("CBB registers returning all 1's which is invalid\n");
579 		return -EINVAL;
580 	}
581 
582 	overflow = readl(cbb->mon + FABRIC_MN_INITIATOR_ERR_OVERFLOW_STATUS_0);
583 
584 	tegra234_cbb_print_error(file, cbb, status, overflow);
585 
586 	error = readl(cbb->mon + FABRIC_MN_INITIATOR_LOG_ERR_STATUS_0);
587 	if (!error) {
588 		pr_info("Error Monitor doesn't have Error Logger\n");
589 		return -EINVAL;
590 	}
591 
592 	cbb->type = 0;
593 
594 	while (error) {
595 		if (error & BIT(0)) {
596 			u32 hi, lo;
597 
598 			hi = readl(cbb->mon + FABRIC_MN_INITIATOR_LOG_ADDR_HIGH_0);
599 			lo = readl(cbb->mon + FABRIC_MN_INITIATOR_LOG_ADDR_LOW_0);
600 
601 			cbb->access = (u64)hi << 32 | lo;
602 
603 			cbb->mn_attr0 = readl(cbb->mon + FABRIC_MN_INITIATOR_LOG_ATTRIBUTES0_0);
604 			cbb->mn_attr1 = readl(cbb->mon + FABRIC_MN_INITIATOR_LOG_ATTRIBUTES1_0);
605 			cbb->mn_attr2 = readl(cbb->mon + FABRIC_MN_INITIATOR_LOG_ATTRIBUTES2_0);
606 			cbb->mn_user_bits = readl(cbb->mon + FABRIC_MN_INITIATOR_LOG_USER_BITS0_0);
607 
608 			print_errlog_err(file, cbb);
609 		}
610 
611 		cbb->type++;
612 		error >>= 1;
613 	}
614 
615 	return 0;
616 }
617 
618 static int print_err_notifier(struct seq_file *file, struct tegra234_cbb *cbb, u32 status)
619 {
620 	unsigned int index = 0;
621 	int err;
622 
623 	pr_crit("**************************************\n");
624 	pr_crit("CPU:%d, Error:%s, Errmon:%d\n", smp_processor_id(),
625 		cbb->fabric->fab_list[cbb->fabric->fab_id].name, status);
626 
627 	while (status) {
628 		if (status & BIT(0)) {
629 			unsigned int notifier = cbb->fabric->notifier_offset;
630 			u32 hi, lo, mask = BIT(index);
631 			phys_addr_t addr;
632 			u64 offset;
633 
634 			writel(mask, cbb->regs + notifier + FABRIC_EN_CFG_ADDR_INDEX_0_0);
635 			hi = readl(cbb->regs + notifier + FABRIC_EN_CFG_ADDR_HI_0);
636 			lo = readl(cbb->regs + notifier + FABRIC_EN_CFG_ADDR_LOW_0);
637 
638 			addr = (u64)hi << 32 | lo;
639 
640 			offset = addr - cbb->res->start;
641 			cbb->mon = cbb->regs + offset;
642 			cbb->mask = BIT(index);
643 
644 			err = print_errmonX_info(file, cbb);
645 			tegra234_cbb_error_clear(&cbb->base);
646 			if (err)
647 				return err;
648 			tegra_cbb_print_err(file, "\t**************************************\n");
649 		}
650 
651 		status >>= 1;
652 		index++;
653 	}
654 
655 	return 0;
656 }
657 
658 #ifdef CONFIG_DEBUG_FS
659 static DEFINE_MUTEX(cbb_debugfs_mutex);
660 
661 static int tegra234_cbb_debugfs_show(struct tegra_cbb *cbb, struct seq_file *file, void *data)
662 {
663 	int err = 0;
664 
665 	mutex_lock(&cbb_debugfs_mutex);
666 
667 	list_for_each_entry(cbb, &cbb_list, node) {
668 		struct tegra234_cbb *priv = to_tegra234_cbb(cbb);
669 		u32 status;
670 
671 		status = tegra_cbb_get_status(&priv->base);
672 		if (status) {
673 			err = print_err_notifier(file, priv, status);
674 			if (err)
675 				break;
676 		}
677 	}
678 
679 	mutex_unlock(&cbb_debugfs_mutex);
680 	return err;
681 }
682 #endif
683 
684 /*
685  * Handler for CBB errors
686  */
687 static irqreturn_t tegra234_cbb_isr(int irq, void *data)
688 {
689 	bool is_inband_err = false;
690 	struct tegra_cbb *cbb;
691 	unsigned long flags;
692 	u8 mstr_id;
693 	int err;
694 
695 	spin_lock_irqsave(&cbb_lock, flags);
696 
697 	list_for_each_entry(cbb, &cbb_list, node) {
698 		struct tegra234_cbb *priv = to_tegra234_cbb(cbb);
699 		u32 status = tegra_cbb_get_status(cbb);
700 
701 		if (status && (irq == priv->sec_irq)) {
702 			tegra_cbb_print_err(NULL, "CPU:%d, Error: %s@0x%llx, irq=%d\n",
703 					    smp_processor_id(),
704 					    priv->fabric->fab_list[priv->fabric->fab_id].name,
705 					    priv->res->start, irq);
706 
707 			err = print_err_notifier(NULL, priv, status);
708 			if (err)
709 				goto unlock;
710 
711 			/*
712 			 * If illegal request is from CCPLEX(id:0x1) initiator then call WARN()
713 			 */
714 			if (priv->fabric->off_mask_erd) {
715 				mstr_id =  FIELD_GET(USRBITS_MSTR_ID, priv->mn_user_bits);
716 				if (mstr_id == CCPLEX_MSTRID)
717 					is_inband_err = 1;
718 			}
719 		}
720 	}
721 
722 unlock:
723 	spin_unlock_irqrestore(&cbb_lock, flags);
724 	WARN_ON(is_inband_err);
725 	return IRQ_HANDLED;
726 }
727 
728 /*
729  * Register handler for CBB_SECURE interrupt for reporting errors
730  */
731 static int tegra234_cbb_interrupt_enable(struct tegra_cbb *cbb)
732 {
733 	struct tegra234_cbb *priv = to_tegra234_cbb(cbb);
734 
735 	if (priv->sec_irq) {
736 		int err = devm_request_irq(cbb->dev, priv->sec_irq, tegra234_cbb_isr, 0,
737 					   dev_name(cbb->dev), priv);
738 		if (err) {
739 			dev_err(cbb->dev, "failed to register interrupt %u: %d\n", priv->sec_irq,
740 				err);
741 			return err;
742 		}
743 	}
744 
745 	return 0;
746 }
747 
748 static void tegra234_cbb_error_enable(struct tegra_cbb *cbb)
749 {
750 	tegra_cbb_fault_enable(cbb);
751 }
752 
753 static const struct tegra_cbb_ops tegra234_cbb_ops = {
754 	.get_status = tegra234_cbb_get_status,
755 	.error_clear = tegra234_cbb_error_clear,
756 	.fault_enable = tegra234_cbb_fault_enable,
757 	.error_enable = tegra234_cbb_error_enable,
758 	.interrupt_enable = tegra234_cbb_interrupt_enable,
759 #ifdef CONFIG_DEBUG_FS
760 	.debugfs_show = tegra234_cbb_debugfs_show,
761 #endif
762 };
763 
764 static const char * const tegra234_initiator_id[] = {
765 	[0x00] = "TZ",
766 	[0x01] = "CCPLEX",
767 	[0x02] = "CCPMU",
768 	[0x03] = "BPMP_FW",
769 	[0x04] = "AON",
770 	[0x05] = "SCE",
771 	[0x06] = "GPCDMA_P",
772 	[0x07] = "TSECA_NONSECURE",
773 	[0x08] = "TSECA_LIGHTSECURE",
774 	[0x09] = "TSECA_HEAVYSECURE",
775 	[0x0a] = "CORESIGHT",
776 	[0x0b] = "APE",
777 	[0x0c] = "PEATRANS",
778 	[0x0d] = "JTAGM_DFT",
779 	[0x0e] = "RCE",
780 	[0x0f] = "DCE",
781 	[0x10] = "PSC_FW_USER",
782 	[0x11] = "PSC_FW_SUPERVISOR",
783 	[0x12] = "PSC_FW_MACHINE",
784 	[0x13] = "PSC_BOOT",
785 	[0x14] = "BPMP_BOOT",
786 	[0x15] = "NVDEC_NONSECURE",
787 	[0x16] = "NVDEC_LIGHTSECURE",
788 	[0x17] = "NVDEC_HEAVYSECURE",
789 	[0x18] = "CBB_INTERNAL",
790 	[0x19] = "RSVD"
791 };
792 
793 static const struct tegra_cbb_error tegra234_cbb_errors[] = {
794 	{
795 		.code = "TARGET_ERR",
796 		.desc = "Target being accessed responded with an error"
797 	}, {
798 		.code = "DECODE_ERR",
799 		.desc = "Attempt to access an address hole"
800 	}, {
801 		.code = "FIREWALL_ERR",
802 		.desc = "Attempt to access a region which is firewall protected"
803 	}, {
804 		.code = "TIMEOUT_ERR",
805 		.desc = "No response returned by target"
806 	}, {
807 		.code = "PWRDOWN_ERR",
808 		.desc = "Attempt to access a portion of fabric that is powered down"
809 	}, {
810 		.code = "UNSUPPORTED_ERR",
811 		.desc = "Attempt to access a target through an unsupported access"
812 	}
813 };
814 
815 static const struct tegra234_target_lookup tegra234_aon_target_map[] = {
816 	{ "AXI2APB", 0x00000 },
817 	{ "AST",     0x14000 },
818 	{ "CBB",     0x15000 },
819 	{ "CPU",     0x16000 },
820 };
821 
822 static const struct tegra234_target_lookup tegra234_bpmp_target_map[] = {
823 	{ "AXI2APB", 0x00000 },
824 	{ "AST0",    0x15000 },
825 	{ "AST1",    0x16000 },
826 	{ "CBB",     0x17000 },
827 	{ "CPU",     0x18000 },
828 };
829 
830 static const struct tegra234_target_lookup tegra234_common_target_map[] = {
831 	{ "AXI2APB", 0x00000 },
832 	{ "AST0",    0x15000 },
833 	{ "AST1",    0x16000 },
834 	{ "CBB",     0x17000 },
835 	{ "RSVD",    0x00000 },
836 	{ "CPU",     0x18000 },
837 };
838 
839 static const struct tegra234_target_lookup tegra234_cbb_target_map[] = {
840 	{ "AON",        0x40000 },
841 	{ "BPMP",       0x41000 },
842 	{ "CBB",        0x42000 },
843 	{ "HOST1X",     0x43000 },
844 	{ "STM",        0x44000 },
845 	{ "FSI",        0x45000 },
846 	{ "PSC",        0x46000 },
847 	{ "PCIE_C1",    0x47000 },
848 	{ "PCIE_C2",    0x48000 },
849 	{ "PCIE_C3",    0x49000 },
850 	{ "PCIE_C0",    0x4a000 },
851 	{ "PCIE_C4",    0x4b000 },
852 	{ "GPU",        0x4c000 },
853 	{ "SMMU0",      0x4d000 },
854 	{ "SMMU1",      0x4e000 },
855 	{ "SMMU2",      0x4f000 },
856 	{ "SMMU3",      0x50000 },
857 	{ "SMMU4",      0x51000 },
858 	{ "PCIE_C10",   0x52000 },
859 	{ "PCIE_C7",    0x53000 },
860 	{ "PCIE_C8",    0x54000 },
861 	{ "PCIE_C9",    0x55000 },
862 	{ "PCIE_C5",    0x56000 },
863 	{ "PCIE_C6",    0x57000 },
864 	{ "DCE",        0x58000 },
865 	{ "RCE",        0x59000 },
866 	{ "SCE",        0x5a000 },
867 	{ "AXI2APB_1",  0x70000 },
868 	{ "AXI2APB_10", 0x71000 },
869 	{ "AXI2APB_11", 0x72000 },
870 	{ "AXI2APB_12", 0x73000 },
871 	{ "AXI2APB_13", 0x74000 },
872 	{ "AXI2APB_14", 0x75000 },
873 	{ "AXI2APB_15", 0x76000 },
874 	{ "AXI2APB_16", 0x77000 },
875 	{ "AXI2APB_17", 0x78000 },
876 	{ "AXI2APB_18", 0x79000 },
877 	{ "AXI2APB_19", 0x7a000 },
878 	{ "AXI2APB_2",  0x7b000 },
879 	{ "AXI2APB_20", 0x7c000 },
880 	{ "AXI2APB_21", 0x7d000 },
881 	{ "AXI2APB_22", 0x7e000 },
882 	{ "AXI2APB_23", 0x7f000 },
883 	{ "AXI2APB_25", 0x80000 },
884 	{ "AXI2APB_26", 0x81000 },
885 	{ "AXI2APB_27", 0x82000 },
886 	{ "AXI2APB_28", 0x83000 },
887 	{ "AXI2APB_29", 0x84000 },
888 	{ "AXI2APB_30", 0x85000 },
889 	{ "AXI2APB_31", 0x86000 },
890 	{ "AXI2APB_32", 0x87000 },
891 	{ "AXI2APB_33", 0x88000 },
892 	{ "AXI2APB_34", 0x89000 },
893 	{ "AXI2APB_35", 0x92000 },
894 	{ "AXI2APB_4",  0x8b000 },
895 	{ "AXI2APB_5",  0x8c000 },
896 	{ "AXI2APB_6",  0x8d000 },
897 	{ "AXI2APB_7",  0x8e000 },
898 	{ "AXI2APB_8",  0x8f000 },
899 	{ "AXI2APB_9",  0x90000 },
900 	{ "AXI2APB_3",  0x91000 },
901 };
902 
903 static const struct tegra234_fabric_lookup tegra234_cbb_fab_list[] = {
904 	[T234_CBB_FABRIC_ID] = { "cbb-fabric", true,
905 				 tegra234_cbb_target_map,
906 				 ARRAY_SIZE(tegra234_cbb_target_map) },
907 	[T234_SCE_FABRIC_ID] = { "sce-fabric", true,
908 				 tegra234_common_target_map,
909 				 ARRAY_SIZE(tegra234_common_target_map) },
910 	[T234_RCE_FABRIC_ID] = { "rce-fabric", true,
911 				 tegra234_common_target_map,
912 				 ARRAY_SIZE(tegra234_common_target_map) },
913 	[T234_DCE_FABRIC_ID] = { "dce-fabric", true,
914 				 tegra234_common_target_map,
915 				 ARRAY_SIZE(tegra234_common_target_map) },
916 	[T234_AON_FABRIC_ID] = { "aon-fabric", true,
917 				 tegra234_aon_target_map,
918 				 ARRAY_SIZE(tegra234_aon_target_map) },
919 	[T234_PSC_FABRIC_ID] = { "psc-fabric" },
920 	[T234_BPMP_FABRIC_ID] = { "bpmp-fabric", true,
921 				 tegra234_bpmp_target_map,
922 				 ARRAY_SIZE(tegra234_bpmp_target_map) },
923 	[T234_FSI_FABRIC_ID] = { "fsi-fabric" },
924 };
925 
926 static const struct tegra234_cbb_fabric tegra234_aon_fabric = {
927 	.fab_id = T234_AON_FABRIC_ID,
928 	.fab_list = tegra234_cbb_fab_list,
929 	.initiator_id = tegra234_initiator_id,
930 	.errors = tegra234_cbb_errors,
931 	.max_errors = ARRAY_SIZE(tegra234_cbb_errors),
932 	.err_intr_enbl = 0x7,
933 	.err_status_clr = 0x3f,
934 	.notifier_offset = 0x17000,
935 	.firewall_base = 0x30000,
936 	.firewall_ctl = 0x8d0,
937 	.firewall_wr_ctl = 0x8c8,
938 };
939 
940 static const struct tegra234_cbb_fabric tegra234_bpmp_fabric = {
941 	.fab_id = T234_BPMP_FABRIC_ID,
942 	.fab_list = tegra234_cbb_fab_list,
943 	.initiator_id = tegra234_initiator_id,
944 	.errors = tegra234_cbb_errors,
945 	.max_errors = ARRAY_SIZE(tegra234_cbb_errors),
946 	.err_intr_enbl = 0xf,
947 	.err_status_clr = 0x3f,
948 	.notifier_offset = 0x19000,
949 	.firewall_base = 0x30000,
950 	.firewall_ctl = 0x8f0,
951 	.firewall_wr_ctl = 0x8e8,
952 };
953 
954 static const struct tegra234_cbb_fabric tegra234_cbb_fabric = {
955 	.fab_id = T234_CBB_FABRIC_ID,
956 	.fab_list = tegra234_cbb_fab_list,
957 	.initiator_id = tegra234_initiator_id,
958 	.errors = tegra234_cbb_errors,
959 	.max_errors = ARRAY_SIZE(tegra234_cbb_errors),
960 	.err_intr_enbl = 0x7f,
961 	.err_status_clr = 0x3f,
962 	.notifier_offset = 0x60000,
963 	.off_mask_erd = 0x3a004,
964 	.firewall_base = 0x10000,
965 	.firewall_ctl = 0x23f0,
966 	.firewall_wr_ctl = 0x23e8,
967 };
968 
969 static const struct tegra234_cbb_fabric tegra234_dce_fabric = {
970 	.fab_id = T234_DCE_FABRIC_ID,
971 	.fab_list = tegra234_cbb_fab_list,
972 	.initiator_id = tegra234_initiator_id,
973 	.errors = tegra234_cbb_errors,
974 	.max_errors = ARRAY_SIZE(tegra234_cbb_errors),
975 	.err_intr_enbl = 0xf,
976 	.err_status_clr = 0x3f,
977 	.notifier_offset = 0x19000,
978 	.firewall_base = 0x30000,
979 	.firewall_ctl = 0x290,
980 	.firewall_wr_ctl = 0x288,
981 };
982 
983 static const struct tegra234_cbb_fabric tegra234_rce_fabric = {
984 	.fab_id = T234_RCE_FABRIC_ID,
985 	.fab_list = tegra234_cbb_fab_list,
986 	.initiator_id = tegra234_initiator_id,
987 	.errors = tegra234_cbb_errors,
988 	.max_errors = ARRAY_SIZE(tegra234_cbb_errors),
989 	.err_intr_enbl = 0xf,
990 	.err_status_clr = 0x3f,
991 	.notifier_offset = 0x19000,
992 	.firewall_base = 0x30000,
993 	.firewall_ctl = 0x290,
994 	.firewall_wr_ctl = 0x288,
995 };
996 
997 static const struct tegra234_cbb_fabric tegra234_sce_fabric = {
998 	.fab_id = T234_SCE_FABRIC_ID,
999 	.fab_list = tegra234_cbb_fab_list,
1000 	.initiator_id = tegra234_initiator_id,
1001 	.errors = tegra234_cbb_errors,
1002 	.max_errors = ARRAY_SIZE(tegra234_cbb_errors),
1003 	.err_intr_enbl = 0xf,
1004 	.err_status_clr = 0x3f,
1005 	.notifier_offset = 0x19000,
1006 	.firewall_base = 0x30000,
1007 	.firewall_ctl = 0x290,
1008 	.firewall_wr_ctl = 0x288,
1009 };
1010 
1011 static const struct tegra234_target_lookup tegra238_ape_target_map[] = {
1012 	{ "AXI2APB", 0x00000 },
1013 	{ "AGIC",    0x15000 },
1014 	{ "AMC",     0x16000 },
1015 	{ "AST0",    0x17000 },
1016 	{ "AST1",    0x18000 },
1017 	{ "AST2",    0x19000 },
1018 	{ "CBB",     0x1A000 },
1019 };
1020 
1021 static const struct tegra234_target_lookup tegra238_cbb_target_map[] = {
1022 	{ "AON",         0x40000 },
1023 	{ "APE",         0x50000 },
1024 	{ "BPMP",        0x41000 },
1025 	{ "HOST1X",      0x43000 },
1026 	{ "STM",         0x44000 },
1027 	{ "CBB_CENTRAL", 0x00000 },
1028 	{ "PCIE_C0",     0x51000 },
1029 	{ "PCIE_C1",     0x47000 },
1030 	{ "PCIE_C2",     0x48000 },
1031 	{ "PCIE_C3",     0x49000 },
1032 	{ "GPU",         0x4C000 },
1033 	{ "SMMU0",       0x4D000 },
1034 	{ "SMMU1",       0x4E000 },
1035 	{ "SMMU2",       0x4F000 },
1036 	{ "PSC",         0x52000 },
1037 	{ "AXI2APB_1",   0x70000 },
1038 	{ "AXI2APB_12",  0x73000 },
1039 	{ "AXI2APB_13",  0x74000 },
1040 	{ "AXI2APB_15",  0x76000 },
1041 	{ "AXI2APB_16",  0x77000 },
1042 	{ "AXI2APB_18",  0x79000 },
1043 	{ "AXI2APB_19",  0x7A000 },
1044 	{ "AXI2APB_2",   0x7B000 },
1045 	{ "AXI2APB_23",  0x7F000 },
1046 	{ "AXI2APB_25",  0x80000 },
1047 	{ "AXI2APB_26",  0x81000 },
1048 	{ "AXI2APB_27",  0x82000 },
1049 	{ "AXI2APB_28",  0x83000 },
1050 	{ "AXI2APB_32",  0x87000 },
1051 	{ "AXI2APB_33",  0x88000 },
1052 	{ "AXI2APB_4",   0x8B000 },
1053 	{ "AXI2APB_5",   0x8C000 },
1054 	{ "AXI2APB_6",   0x93000 },
1055 	{ "AXI2APB_9",   0x90000 },
1056 	{ "AXI2APB_3",   0x91000 },
1057 };
1058 
1059 static const struct tegra234_fabric_lookup tegra238_cbb_fab_list[] = {
1060 	[T238_CBB_FABRIC_ID]  = { "cbb-fabric", true,
1061 				  tegra238_cbb_target_map,
1062 				  ARRAY_SIZE(tegra238_cbb_target_map) },
1063 	[T238_AON_FABRIC_ID]  = { "aon-fabric", true,
1064 				  tegra234_aon_target_map,
1065 				  ARRAY_SIZE(tegra234_aon_target_map) },
1066 	[T238_PSC_FABRIC_ID]  = { "psc-fabric" },
1067 	[T238_BPMP_FABRIC_ID] = { "bpmp-fabric", true,
1068 				  tegra234_bpmp_target_map,
1069 				  ARRAY_SIZE(tegra234_bpmp_target_map) },
1070 	[T238_APE_FABRIC_ID]  = { "ape-fabric", true,
1071 				  tegra238_ape_target_map,
1072 				  ARRAY_SIZE(tegra238_ape_target_map) },
1073 };
1074 
1075 static const struct tegra234_cbb_fabric tegra238_aon_fabric = {
1076 	.fab_id = T238_AON_FABRIC_ID,
1077 	.fab_list = tegra238_cbb_fab_list,
1078 	.initiator_id = tegra234_initiator_id,
1079 	.errors = tegra234_cbb_errors,
1080 	.max_errors = ARRAY_SIZE(tegra234_cbb_errors),
1081 	.err_intr_enbl = 0x7,
1082 	.err_status_clr = 0x3f,
1083 	.notifier_offset = 0x17000,
1084 	.firewall_base = 0x30000,
1085 	.firewall_ctl = 0x8f0,
1086 	.firewall_wr_ctl = 0x8e8,
1087 };
1088 
1089 static const struct tegra234_cbb_fabric tegra238_ape_fabric = {
1090 	.fab_id = T238_APE_FABRIC_ID,
1091 	.fab_list = tegra238_cbb_fab_list,
1092 	.initiator_id = tegra234_initiator_id,
1093 	.errors = tegra234_cbb_errors,
1094 	.max_errors = ARRAY_SIZE(tegra234_cbb_errors),
1095 	.err_intr_enbl = 0xf,
1096 	.err_status_clr = 0x3f,
1097 	.notifier_offset = 0x1E000,
1098 	.firewall_base = 0x30000,
1099 	.firewall_ctl = 0xad0,
1100 	.firewall_wr_ctl = 0xac8,
1101 };
1102 
1103 static const struct tegra234_cbb_fabric tegra238_bpmp_fabric = {
1104 	.fab_id = T238_BPMP_FABRIC_ID,
1105 	.fab_list = tegra238_cbb_fab_list,
1106 	.initiator_id = tegra234_initiator_id,
1107 	.errors = tegra234_cbb_errors,
1108 	.max_errors = ARRAY_SIZE(tegra234_cbb_errors),
1109 	.err_intr_enbl = 0xf,
1110 	.err_status_clr = 0x3f,
1111 	.notifier_offset = 0x19000,
1112 	.firewall_base = 0x30000,
1113 	.firewall_ctl = 0x8f0,
1114 	.firewall_wr_ctl = 0x8e8,
1115 };
1116 
1117 static const struct tegra234_cbb_fabric tegra238_cbb_fabric = {
1118 	.fab_id = T238_CBB_FABRIC_ID,
1119 	.fab_list = tegra238_cbb_fab_list,
1120 	.initiator_id = tegra234_initiator_id,
1121 	.errors = tegra234_cbb_errors,
1122 	.max_errors = ARRAY_SIZE(tegra234_cbb_errors),
1123 	.err_intr_enbl = 0x3f,
1124 	.err_status_clr = 0x3f,
1125 	.notifier_offset = 0x60000,
1126 	.off_mask_erd = 0x3d004,
1127 	.firewall_base = 0x10000,
1128 	.firewall_ctl = 0x2230,
1129 	.firewall_wr_ctl = 0x2228,
1130 };
1131 
1132 static const char * const tegra241_initiator_id[] = {
1133 	[0x0] = "TZ",
1134 	[0x1] = "CCPLEX",
1135 	[0x2] = "CCPMU",
1136 	[0x3] = "BPMP_FW",
1137 	[0x4] = "PSC_FW_USER",
1138 	[0x5] = "PSC_FW_SUPERVISOR",
1139 	[0x6] = "PSC_FW_MACHINE",
1140 	[0x7] = "PSC_BOOT",
1141 	[0x8] = "BPMP_BOOT",
1142 	[0x9] = "JTAGM_DFT",
1143 	[0xa] = "CORESIGHT",
1144 	[0xb] = "GPU",
1145 	[0xc] = "PEATRANS",
1146 	[0xd ... 0x3f] = "RSVD"
1147 };
1148 
1149 /*
1150  * Possible causes for Target and Timeout errors.
1151  * TARGET_ERR:
1152  * Target being accessed responded with an error. Target could return
1153  * an error for various cases :
1154  *   Unsupported access, clamp setting when power gated, register
1155  *   level firewall(SCR), address hole within the target, etc
1156  *
1157  * TIMEOUT_ERR:
1158  * No response returned by target. Can be due to target being clock
1159  * gated, under reset, powered down or target inability to respond
1160  * for an internal target issue
1161  */
1162 static const struct tegra_cbb_error tegra241_cbb_errors[] = {
1163 	{
1164 		.code = "TARGET_ERR",
1165 		.desc = "Target being accessed responded with an error."
1166 	}, {
1167 		.code = "DECODE_ERR",
1168 		.desc = "Attempt to access an address hole or Reserved region of memory."
1169 	}, {
1170 		.code = "FIREWALL_ERR",
1171 		.desc = "Attempt to access a region which is firewalled."
1172 	}, {
1173 		.code = "TIMEOUT_ERR",
1174 		.desc = "No response returned by target."
1175 	}, {
1176 		.code = "PWRDOWN_ERR",
1177 		.desc = "Attempt to access a portion of the fabric that is powered down."
1178 	}, {
1179 		.code = "UNSUPPORTED_ERR",
1180 		.desc = "Attempt to access a target through an unsupported access."
1181 	}, {
1182 		.code = "POISON_ERR",
1183 		.desc = "Target responds with poison error to indicate error in data."
1184 	}, {
1185 		.code = "RSVD"
1186 	}, {
1187 		.code = "RSVD"
1188 	}, {
1189 		.code = "RSVD"
1190 	}, {
1191 		.code = "RSVD"
1192 	}, {
1193 		.code = "RSVD"
1194 	}, {
1195 		.code = "RSVD"
1196 	}, {
1197 		.code = "RSVD"
1198 	}, {
1199 		.code = "RSVD"
1200 	}, {
1201 		.code = "RSVD"
1202 	}, {
1203 		.code = "NO_SUCH_ADDRESS_ERR",
1204 		.desc = "The address belongs to the pri_target range but there is no register "
1205 			"implemented at the address."
1206 	}, {
1207 		.code = "TASK_ERR",
1208 		.desc = "Attempt to update a PRI task when the current task has still not "
1209 			"completed."
1210 	}, {
1211 		.code = "EXTERNAL_ERR",
1212 		.desc = "Indicates that an external PRI register access met with an error due to "
1213 			"any issue in the unit."
1214 	}, {
1215 		.code = "INDEX_ERR",
1216 		.desc = "Applicable to PRI index aperture pair, when the programmed index is "
1217 			"outside the range defined in the manual."
1218 	}, {
1219 		.code = "RESET_ERR",
1220 		.desc = "Target in Reset Error: Attempt to access a SubPri or external PRI "
1221 			"register but they are in reset."
1222 	}, {
1223 		.code = "REGISTER_RST_ERR",
1224 		.desc = "Attempt to access a PRI register but the register is partial or "
1225 			"completely in reset."
1226 	}, {
1227 		.code = "POWER_GATED_ERR",
1228 		.desc = "Returned by external PRI client when the external access goes to a power "
1229 			"gated domain."
1230 	}, {
1231 		.code = "SUBPRI_FS_ERR",
1232 		.desc = "Subpri is floorswept: Attempt to access a subpri through the main pri "
1233 			"target but subPri logic is floorswept."
1234 	}, {
1235 		.code = "SUBPRI_CLK_OFF_ERR",
1236 		.desc = "Subpri clock is off: Attempt to access a subpri through the main pri "
1237 			"target but subPris clock is gated/off."
1238 	},
1239 };
1240 
1241 static const struct tegra234_target_lookup tegra241_bpmp_target_map[] = {
1242 	{ "RSVD",    0x00000 },
1243 	{ "RSVD",    0x00000 },
1244 	{ "RSVD",    0x00000 },
1245 	{ "CBB",     0x15000 },
1246 	{ "CPU",     0x16000 },
1247 	{ "AXI2APB", 0x00000 },
1248 	{ "DBB0",    0x17000 },
1249 	{ "DBB1",    0x18000 },
1250 };
1251 
1252 static const struct tegra234_target_lookup tegra241_cbb_target_map[] = {
1253 	{ "RSVD",       0x00000 },
1254 	{ "PCIE_C8",    0x51000 },
1255 	{ "PCIE_C9",    0x52000 },
1256 	{ "RSVD",       0x00000 },
1257 	{ "RSVD",       0x00000 },
1258 	{ "RSVD",       0x00000 },
1259 	{ "RSVD",       0x00000 },
1260 	{ "RSVD",       0x00000 },
1261 	{ "RSVD",       0x00000 },
1262 	{ "RSVD",       0x00000 },
1263 	{ "RSVD",       0x00000 },
1264 	{ "AON",        0x5b000 },
1265 	{ "BPMP",       0x5c000 },
1266 	{ "RSVD",       0x00000 },
1267 	{ "RSVD",       0x00000 },
1268 	{ "PSC",        0x5d000 },
1269 	{ "STM",        0x5e000 },
1270 	{ "AXI2APB_1",  0x70000 },
1271 	{ "AXI2APB_10", 0x71000 },
1272 	{ "AXI2APB_11", 0x72000 },
1273 	{ "AXI2APB_12", 0x73000 },
1274 	{ "AXI2APB_13", 0x74000 },
1275 	{ "AXI2APB_14", 0x75000 },
1276 	{ "AXI2APB_15", 0x76000 },
1277 	{ "AXI2APB_16", 0x77000 },
1278 	{ "AXI2APB_17", 0x78000 },
1279 	{ "AXI2APB_18", 0x79000 },
1280 	{ "AXI2APB_19", 0x7a000 },
1281 	{ "AXI2APB_2",  0x7b000 },
1282 	{ "AXI2APB_20", 0x7c000 },
1283 	{ "AXI2APB_4",  0x87000 },
1284 	{ "AXI2APB_5",  0x88000 },
1285 	{ "AXI2APB_6",  0x89000 },
1286 	{ "AXI2APB_7",  0x8a000 },
1287 	{ "AXI2APB_8",  0x8b000 },
1288 	{ "AXI2APB_9",  0x8c000 },
1289 	{ "AXI2APB_3",  0x8d000 },
1290 	{ "AXI2APB_21", 0x7d000 },
1291 	{ "AXI2APB_22", 0x7e000 },
1292 	{ "AXI2APB_23", 0x7f000 },
1293 	{ "AXI2APB_24", 0x80000 },
1294 	{ "AXI2APB_25", 0x81000 },
1295 	{ "AXI2APB_26", 0x82000 },
1296 	{ "AXI2APB_27", 0x83000 },
1297 	{ "AXI2APB_28", 0x84000 },
1298 	{ "PCIE_C4",    0x53000 },
1299 	{ "PCIE_C5",    0x54000 },
1300 	{ "PCIE_C6",    0x55000 },
1301 	{ "PCIE_C7",    0x56000 },
1302 	{ "PCIE_C2",    0x57000 },
1303 	{ "PCIE_C3",    0x58000 },
1304 	{ "PCIE_C0",    0x59000 },
1305 	{ "PCIE_C1",    0x5a000 },
1306 	{ "CCPLEX",     0x50000 },
1307 	{ "AXI2APB_29", 0x85000 },
1308 	{ "AXI2APB_30", 0x86000 },
1309 	{ "CBB_CENTRAL", 0x00000 },
1310 	{ "AXI2APB_31", 0x8E000 },
1311 	{ "AXI2APB_32", 0x8F000 },
1312 };
1313 
1314 static const struct tegra234_fabric_lookup tegra241_cbb_fab_list[] = {
1315 	[T234_CBB_FABRIC_ID]  = { "cbb-fabric", true,
1316 				  tegra241_cbb_target_map, ARRAY_SIZE(tegra241_cbb_target_map) },
1317 	[T234_BPMP_FABRIC_ID] = { "bpmp-fabric", true,
1318 				  tegra241_bpmp_target_map, ARRAY_SIZE(tegra241_bpmp_target_map) },
1319 };
1320 static const struct tegra234_cbb_fabric tegra241_cbb_fabric = {
1321 	.fab_id = T234_CBB_FABRIC_ID,
1322 	.fab_list = tegra241_cbb_fab_list,
1323 	.initiator_id = tegra241_initiator_id,
1324 	.errors = tegra241_cbb_errors,
1325 	.max_errors = ARRAY_SIZE(tegra241_cbb_errors),
1326 	.err_intr_enbl = 0x7,
1327 	.err_status_clr = 0x1ff007f,
1328 	.notifier_offset = 0x60000,
1329 	.off_mask_erd = 0x40004,
1330 	.firewall_base = 0x20000,
1331 	.firewall_ctl = 0x2370,
1332 	.firewall_wr_ctl = 0x2368,
1333 };
1334 
1335 static const struct tegra234_cbb_fabric tegra241_bpmp_fabric = {
1336 	.fab_id = T234_BPMP_FABRIC_ID,
1337 	.fab_list = tegra241_cbb_fab_list,
1338 	.initiator_id = tegra241_initiator_id,
1339 	.errors = tegra241_cbb_errors,
1340 	.max_errors = ARRAY_SIZE(tegra241_cbb_errors),
1341 	.err_intr_enbl = 0xf,
1342 	.err_status_clr = 0x1ff007f,
1343 	.notifier_offset = 0x19000,
1344 	.firewall_base = 0x30000,
1345 	.firewall_ctl = 0x8f0,
1346 	.firewall_wr_ctl = 0x8e8,
1347 };
1348 
1349 static const char * const tegra264_initiator_id[] = {
1350 	[0x0] = "TZ",
1351 	[0x1] = "CCPLEX",
1352 	[0x2] = "ISC",
1353 	[0x3] = "BPMP_FW",
1354 	[0x4] = "AON",
1355 	[0x5] = "MSS_SEQ",
1356 	[0x6] = "GPCDMA_P",
1357 	[0x7] = "TSECA_NONSECURE",
1358 	[0x8] = "TSECA_LIGHTSECURE",
1359 	[0x9] = "TSECA_HEAVYSECURE",
1360 	[0xa] = "CORESIGHT",
1361 	[0xb] = "APE_0",
1362 	[0xc] = "APE_1",
1363 	[0xd] = "PEATRANS",
1364 	[0xe] = "JTAGM_DFT",
1365 	[0xf] = "RCE",
1366 	[0x10] = "DCE",
1367 	[0x11] = "PSC_FW_USER",
1368 	[0x12] = "PSC_FW_SUPERVISOR",
1369 	[0x13] = "PSC_FW_MACHINE",
1370 	[0x14] = "PSC_BOOT",
1371 	[0x15] = "BPMP_BOOT",
1372 	[0x16] = "GPU_0",
1373 	[0x17] = "GPU_1",
1374 	[0x18] = "GPU_2",
1375 	[0x19] = "GPU_3",
1376 	[0x1a] = "GPU_4",
1377 	[0x1b] = "PSC_EXT_BOOT",
1378 	[0x1c] = "PSC_EXT_RUNTIME",
1379 	[0x1d] = "OESP_EXT",
1380 	[0x1e] = "SB_EXT",
1381 	[0x1f] = "FSI_SAFETY_0",
1382 	[0x20] = "FSI_SAFETY_1",
1383 	[0x21] = "FSI_SAFETY_2",
1384 	[0x22] = "FSI_SAFETY_3",
1385 	[0x23] = "FSI_CHSM",
1386 	[0x24] = "RCE_1",
1387 	[0x25] = "BPMP_OEM_FW",
1388 	[0x26 ... 0x3d] = "RSVD",
1389 	[0x3e] = "CBB_SMN",
1390 	[0x3f] = "CBB_RSVD"
1391 };
1392 
1393 static const struct tegra234_target_lookup tegra264_top0_cbb_target_map[] = {
1394 	{ "RSVD",               0x000000 },
1395 	{ "CBB_CENTRAL",        0xC020000 },
1396 	{ "AXI2APB_1",          0x80000 },
1397 	{ "AXI2APB_10",         0x81000 },
1398 	{ "AXI2APB_11",         0x82000 },
1399 	{ "RSVD",               0x00000 },
1400 	{ "RSVD",               0x00000 },
1401 	{ "AXI2APB_14",         0x83000 },
1402 	{ "AXI2APB_15",         0x84000 },
1403 	{ "AXI2APB_16",         0x85000 },
1404 	{ "AXI2APB_17",         0x86000 },
1405 	{ "AXI2APB_2",          0x87000 },
1406 	{ "AXI2APB_3",          0x88000 },
1407 	{ "RSVD",               0x00000 },
1408 	{ "AXI2APB_5",          0x8A000 },
1409 	{ "AXI2APB_6",          0x8B000 },
1410 	{ "AXI2APB_7",          0x8C000 },
1411 	{ "AXI2APB_8",          0x8D000 },
1412 	{ "AXI2APB_9",          0x8E000 },
1413 	{ "FSI_SLAVE",          0x64000 },
1414 	{ "DISP_USB_CBB_T",     0x65000 },
1415 	{ "SYSTEM_CBB_T",       0x66000 },
1416 	{ "UPHY0_CBB_T",        0x67000 },
1417 	{ "VISION_CBB_T",       0x68000 },
1418 	{ "CCPLEX_SLAVE",       0x69000 },
1419 	{ "PCIE_C0",            0x6A000 },
1420 	{ "SMN_UCF_RX_0",       0x6B000 },
1421 	{ "SMN_UCF_RX_1",       0x6C000 },
1422 	{ "AXI2APB_4",          0x89000 },
1423 };
1424 
1425 static const struct tegra234_target_lookup tegra264_sys_cbb_target_map[] = {
1426 	{ "RSVD",               0x00000 },
1427 	{ "AXI2APB_1",          0xE1000 },
1428 	{ "RSVD",               0x00000 },
1429 	{ "AON_SLAVE",          0x79000 },
1430 	{ "APE_SLAVE",          0x73000 },
1431 	{ "BPMP_SLAVE",         0x74000 },
1432 	{ "OESP_SLAVE",         0x75000 },
1433 	{ "PSC_SLAVE",          0x76000 },
1434 	{ "SB_SLAVE",           0x7A000 },
1435 	{ "SMN_SYSTEM_RX",      0x7B000 },
1436 	{ "STM",                0x77000 },
1437 	{ "RSVD",               0x00000 },
1438 	{ "AXI2APB_3",          0xE3000 },
1439 	{ "TOP_CBB_T",          0x7C000 },
1440 	{ "AXI2APB_2",          0xE4000 },
1441 	{ "AXI2APB_4",          0xE5000 },
1442 	{ "AXI2APB_5",          0xE6000 },
1443 };
1444 
1445 static const struct tegra234_target_lookup tegra264_uphy0_cbb_target_map[] = {
1446 	[0 ... 20] =  { "RSVD", 0x00000 },
1447 	{ "AXI2APB_1",          0x71000 },
1448 	{ "RSVD",               0x00000 },
1449 	{ "AXI2APB_3",          0x75000 },
1450 	{ "SMN_UPHY0_RX",       0x53000 },
1451 	{ "RSVD",               0x00000 },
1452 	{ "RSVD",               0x00000 },
1453 	{ "RSVD",               0x00000 },
1454 	{ "RSVD",               0x00000 },
1455 	{ "PCIE_C4",            0x4B000 },
1456 	{ "AXI2APB_2",          0x74000 },
1457 	{ "AXI2APB_4",          0x76000 },
1458 	{ "AXI2APB_5",          0x77000 },
1459 	{ "RSVD",               0x00000 },
1460 	{ "AXI2APB_7",          0x79000 },
1461 	{ "PCIE_C2",            0x56000 },
1462 	{ "RSVD",               0x00000 },
1463 	{ "RSVD",               0x00000 },
1464 	{ "PCIE_C1",            0x55000 },
1465 	{ "RSVD",               0x00000 },
1466 	{ "AXI2APB_10",         0x72000 },
1467 	{ "AXI2APB_11",         0x7C000 },
1468 	{ "AXI2APB_8",          0x7A000 },
1469 	{ "AXI2APB_9",          0x7B000 },
1470 	{ "RSVD",               0x00000 },
1471 	{ "RSVD",               0x00000 },
1472 	{ "PCIE_C5",            0x4E000 },
1473 	{ "PCIE_C3",            0x58000 },
1474 	{ "RSVD",               0x00000 },
1475 	{ "ISC_SLAVE",          0x54000 },
1476 	{ "TOP_CBB_T",          0x57000 },
1477 	{ "AXI2APB_12",         0x7D000 },
1478 	{ "AXI2APB_13",         0x70000 },
1479 	{ "AXI2APB_6",          0x7E000 },
1480 };
1481 
1482 static const struct tegra234_target_lookup tegra264_vision_cbb_target_map[] = {
1483 	[0 ... 5] =       { "RSVD", 0x0 },
1484 	{ "HOST1X",             0x45000 },
1485 	{ "RSVD",               0x00000 },
1486 	{ "RSVD",               0x00000 },
1487 	{ "AXI2APB_2",          0x71000 },
1488 	{ "RSVD",               0x00000 },
1489 	{ "RSVD",               0x00000 },
1490 	{ "SMN_VISION_RX",      0x47000 },
1491 	[13 ... 19] =     { "RSVD", 0x0 },
1492 	{ "RCE_0_SLAVE",        0x4B000 },
1493 	{ "RCE_1_SLAVE",        0x4C000 },
1494 	{ "AXI2APB_1",          0x72000 },
1495 	{ "AXI2APB_3",          0x73000 },
1496 	{ "TOP_CBB_T",          0x4D000 },
1497 
1498 };
1499 
1500 static const struct tegra234_fabric_lookup tegra264_cbb_fab_list[] = {
1501 	[T264_SYSTEM_CBB_FABRIC_ID]   = { "system-cbb-fabric", true,
1502 					  tegra264_sys_cbb_target_map,
1503 					  ARRAY_SIZE(tegra264_sys_cbb_target_map) },
1504 	[T264_TOP_0_CBB_FABRIC_ID]    = { "top0-cbb-fabric", true,
1505 					  tegra264_top0_cbb_target_map,
1506 					  ARRAY_SIZE(tegra264_top0_cbb_target_map) },
1507 	[T264_VISION_CBB_FABRIC_ID]   = { "vision-cbb-fabric", true,
1508 					  tegra264_vision_cbb_target_map,
1509 					  ARRAY_SIZE(tegra264_vision_cbb_target_map) },
1510 	[T264_DISP_USB_CBB_FABRIC_ID] = { "disp-usb-cbb-fabric" },
1511 	[T264_UPHY0_CBB_FABRIC_ID]    = { "uphy0-cbb-fabric", true,
1512 					  tegra264_uphy0_cbb_target_map,
1513 					  ARRAY_SIZE(tegra264_uphy0_cbb_target_map) },
1514 	[T264_AON_FABRIC_ID]          = { "aon-fabric" },
1515 	[T264_PSC_FABRIC_ID]          = { "psc-fabric" },
1516 	[T264_OESP_FABRIC_ID]         = { "oesp-fabric" },
1517 	[T264_APE_FABRIC_ID]          = { "ape-fabirc" },
1518 	[T264_BPMP_FABRIC_ID]         = { "bpmp-fabric" },
1519 	[T264_RCE_0_FABRIC_ID]        = { "rce0-fabric" },
1520 	[T264_RCE_1_FABRIC_ID]        = { "rce1-fabric" },
1521 	[T264_DCE_FABRIC_ID]          = { "dce-fabric" },
1522 	[T264_FSI_FABRIC_ID]          = { "fsi-fabric" },
1523 	[T264_ISC_FABRIC_ID]          = { "isc-fabric" },
1524 	[T264_SB_FABRIC_ID]           = { "sb-fabric" },
1525 	[T264_ISC_CPU_FABRIC_ID]      = { "isc-cpu-fabric" },
1526 };
1527 
1528 static const struct tegra234_cbb_fabric tegra264_top0_cbb_fabric = {
1529 	.fab_id = T264_TOP_0_CBB_FABRIC_ID,
1530 	.fab_list = tegra264_cbb_fab_list,
1531 	.initiator_id = tegra264_initiator_id,
1532 	.errors = tegra241_cbb_errors,
1533 	.max_errors = ARRAY_SIZE(tegra241_cbb_errors),
1534 	.err_intr_enbl = 0x7,
1535 	.err_status_clr = 0x1ff007f,
1536 	.notifier_offset = 0x90000,
1537 	.off_mask_erd    = 0x4a004,
1538 	.firewall_base   = 0x3c0000,
1539 	.firewall_ctl    = 0x5b0,
1540 	.firewall_wr_ctl = 0x5a8,
1541 };
1542 
1543 static const struct tegra234_cbb_fabric tegra264_sys_cbb_fabric = {
1544 	.fab_id = T264_SYSTEM_CBB_FABRIC_ID,
1545 	.fab_list = tegra264_cbb_fab_list,
1546 	.initiator_id = tegra264_initiator_id,
1547 	.errors = tegra241_cbb_errors,
1548 	.max_errors = ARRAY_SIZE(tegra241_cbb_errors),
1549 	.err_intr_enbl = 0xf,
1550 	.err_status_clr = 0x1ff007f,
1551 	.notifier_offset = 0x40000,
1552 	.firewall_base   = 0x29c000,
1553 	.firewall_ctl    = 0x170,
1554 	.firewall_wr_ctl = 0x168,
1555 };
1556 
1557 static const struct tegra234_cbb_fabric tegra264_uphy0_cbb_fabric = {
1558 	.fab_id = T264_UPHY0_CBB_FABRIC_ID,
1559 	.fab_list = tegra264_cbb_fab_list,
1560 	.initiator_id = tegra264_initiator_id,
1561 	.errors = tegra241_cbb_errors,
1562 	.max_errors = ARRAY_SIZE(tegra241_cbb_errors),
1563 	.err_intr_enbl = 0x1,
1564 	.err_status_clr = 0x1ff007f,
1565 	.notifier_offset = 0x80000,
1566 	.firewall_base   = 0x360000,
1567 	.firewall_ctl    = 0x590,
1568 	.firewall_wr_ctl = 0x588,
1569 };
1570 
1571 static const struct tegra234_cbb_fabric tegra264_vision_cbb_fabric = {
1572 	.fab_id = T264_VISION_CBB_FABRIC_ID,
1573 	.fab_list = tegra264_cbb_fab_list,
1574 	.initiator_id = tegra264_initiator_id,
1575 	.errors = tegra241_cbb_errors,
1576 	.max_errors = ARRAY_SIZE(tegra241_cbb_errors),
1577 	.err_intr_enbl = 0x1,
1578 	.err_status_clr = 0x1ff007f,
1579 	.notifier_offset = 0x80000,
1580 	.firewall_base   = 0x290000,
1581 	.firewall_ctl    = 0x5d0,
1582 	.firewall_wr_ctl = 0x5c8,
1583 };
1584 
1585 static const struct tegra234_fabric_lookup t254_cbb_fab_list[] = {
1586 	[T254_C2C_FABRIC_ID] = { "c2c-fabric", true },
1587 	[T254_DISP_CLUSTER_FABRIC_ID] = { "display-cluster-fabric", true },
1588 	[T254_GPU_FABRIC_ID] = { "gpu-fabric", true },
1589 };
1590 
1591 static const struct tegra234_cbb_fabric t254_c2c_fabric = {
1592 	.fab_id = T254_C2C_FABRIC_ID,
1593 	.fab_list = t254_cbb_fab_list,
1594 	.errors = tegra241_cbb_errors,
1595 	.max_errors = ARRAY_SIZE(tegra241_cbb_errors),
1596 	.err_intr_enbl = 0xf,
1597 	.err_status_clr = 0x1ff007f,
1598 	.notifier_offset = 0x50000,
1599 	.off_mask_erd = 0x14004,
1600 	.firewall_base = 0x40000,
1601 	.firewall_ctl = 0x9b0,
1602 	.firewall_wr_ctl = 0x9a8,
1603 };
1604 
1605 static const struct tegra234_cbb_fabric t254_disp_fabric = {
1606 	.fab_id = T254_DISP_CLUSTER_FABRIC_ID,
1607 	.fab_list = t254_cbb_fab_list,
1608 	.errors = tegra241_cbb_errors,
1609 	.max_errors = ARRAY_SIZE(tegra241_cbb_errors),
1610 	.err_intr_enbl = 0x1,
1611 	.err_status_clr = 0x1ff007f,
1612 	.notifier_offset = 0x50000,
1613 	.firewall_base = 0x30000,
1614 	.firewall_ctl = 0x810,
1615 	.firewall_wr_ctl = 0x808,
1616 };
1617 
1618 static const struct tegra234_cbb_fabric t254_gpu_fabric = {
1619 	.fab_id = T254_GPU_FABRIC_ID,
1620 	.fab_list = t254_cbb_fab_list,
1621 	.errors = tegra241_cbb_errors,
1622 	.max_errors = ARRAY_SIZE(tegra241_cbb_errors),
1623 	.err_intr_enbl = 0x1f,
1624 	.err_status_clr = 0x1ff007f,
1625 	.notifier_offset = 0x50000,
1626 	.firewall_base = 0x30000,
1627 	.firewall_ctl = 0x930,
1628 	.firewall_wr_ctl = 0x928,
1629 };
1630 
1631 static const struct of_device_id tegra234_cbb_dt_ids[] = {
1632 	{ .compatible = "nvidia,tegra234-cbb-fabric", .data = &tegra234_cbb_fabric },
1633 	{ .compatible = "nvidia,tegra234-aon-fabric", .data = &tegra234_aon_fabric },
1634 	{ .compatible = "nvidia,tegra234-bpmp-fabric", .data = &tegra234_bpmp_fabric },
1635 	{ .compatible = "nvidia,tegra234-dce-fabric", .data = &tegra234_dce_fabric },
1636 	{ .compatible = "nvidia,tegra234-rce-fabric", .data = &tegra234_rce_fabric },
1637 	{ .compatible = "nvidia,tegra234-sce-fabric", .data = &tegra234_sce_fabric },
1638 	{ .compatible = "nvidia,tegra238-aon-fabric", .data = &tegra238_aon_fabric },
1639 	{ .compatible = "nvidia,tegra238-ape-fabric", .data = &tegra238_ape_fabric },
1640 	{ .compatible = "nvidia,tegra238-bpmp-fabric", .data = &tegra238_bpmp_fabric },
1641 	{ .compatible = "nvidia,tegra238-cbb-fabric", .data = &tegra238_cbb_fabric },
1642 	{ .compatible = "nvidia,tegra264-sys-cbb-fabric", .data = &tegra264_sys_cbb_fabric },
1643 	{ .compatible = "nvidia,tegra264-top0-cbb-fabric", .data = &tegra264_top0_cbb_fabric },
1644 	{ .compatible = "nvidia,tegra264-uphy0-cbb-fabric", .data = &tegra264_uphy0_cbb_fabric },
1645 	{ .compatible = "nvidia,tegra264-vision-cbb-fabric", .data = &tegra264_vision_cbb_fabric },
1646 	{ /* sentinel */ },
1647 };
1648 MODULE_DEVICE_TABLE(of, tegra234_cbb_dt_ids);
1649 
1650 struct tegra234_cbb_acpi_uid {
1651 	const char *hid;
1652 	const char *uid;
1653 	const struct tegra234_cbb_fabric *fabric;
1654 };
1655 
1656 static const struct tegra234_cbb_acpi_uid tegra234_cbb_acpi_uids[] = {
1657 	{ "NVDA1070", "1", &tegra241_cbb_fabric },
1658 	{ "NVDA1070", "2", &tegra241_bpmp_fabric },
1659 	{ "NVDA1070", "3", &t254_c2c_fabric },
1660 	{ "NVDA1070", "4", &t254_disp_fabric },
1661 	{ "NVDA1070", "5", &t254_gpu_fabric },
1662 	{ },
1663 };
1664 
1665 static const struct
1666 tegra234_cbb_fabric *tegra234_cbb_acpi_get_fabric(struct acpi_device *adev)
1667 {
1668 	const struct tegra234_cbb_acpi_uid *entry;
1669 
1670 	for (entry = tegra234_cbb_acpi_uids; entry->hid; entry++) {
1671 		if (acpi_dev_hid_uid_match(adev, entry->hid, entry->uid))
1672 			return entry->fabric;
1673 	}
1674 
1675 	return NULL;
1676 }
1677 
1678 static const struct acpi_device_id tegra241_cbb_acpi_ids[] = {
1679 	{ "NVDA1070" },
1680 	{ },
1681 };
1682 MODULE_DEVICE_TABLE(acpi, tegra241_cbb_acpi_ids);
1683 
1684 static int tegra234_cbb_probe(struct platform_device *pdev)
1685 {
1686 	const struct tegra234_cbb_fabric *fabric;
1687 	struct tegra234_cbb *cbb;
1688 	unsigned long flags = 0;
1689 	int err;
1690 
1691 	if (pdev->dev.of_node) {
1692 		fabric = of_device_get_match_data(&pdev->dev);
1693 	} else {
1694 		struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
1695 		if (!device)
1696 			return -ENODEV;
1697 
1698 		fabric = tegra234_cbb_acpi_get_fabric(device);
1699 		if (!fabric) {
1700 			dev_err(&pdev->dev, "no device match found\n");
1701 			return -ENODEV;
1702 		}
1703 	}
1704 
1705 	cbb = devm_kzalloc(&pdev->dev, sizeof(*cbb), GFP_KERNEL);
1706 	if (!cbb)
1707 		return -ENOMEM;
1708 
1709 	INIT_LIST_HEAD(&cbb->base.node);
1710 	cbb->base.ops = &tegra234_cbb_ops;
1711 	cbb->base.dev = &pdev->dev;
1712 	cbb->fabric = fabric;
1713 
1714 	cbb->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &cbb->res);
1715 	if (IS_ERR(cbb->regs))
1716 		return PTR_ERR(cbb->regs);
1717 
1718 	err = tegra_cbb_get_irq(pdev, NULL, &cbb->sec_irq);
1719 	if (err)
1720 		return err;
1721 
1722 	platform_set_drvdata(pdev, cbb);
1723 
1724 	/*
1725 	 * Don't enable error reporting for a Fabric if write to it's registers
1726 	 * is blocked by CBB firewall.
1727 	 */
1728 	if (!tegra234_cbb_write_access_allowed(pdev, cbb)) {
1729 		dev_info(&pdev->dev, "error reporting not enabled due to firewall\n");
1730 		return 0;
1731 	}
1732 
1733 	spin_lock_irqsave(&cbb_lock, flags);
1734 	list_add(&cbb->base.node, &cbb_list);
1735 	spin_unlock_irqrestore(&cbb_lock, flags);
1736 
1737 	/* set ERD bit to mask SError and generate interrupt to report error */
1738 	if (cbb->fabric->off_mask_erd)
1739 		tegra234_cbb_mask_serror(cbb);
1740 
1741 	return tegra_cbb_register(&cbb->base);
1742 }
1743 
1744 static int __maybe_unused tegra234_cbb_resume_noirq(struct device *dev)
1745 {
1746 	struct tegra234_cbb *cbb = dev_get_drvdata(dev);
1747 
1748 	/* set ERD bit to mask SError and generate interrupt to report error */
1749 	if (cbb->fabric->off_mask_erd)
1750 		tegra234_cbb_mask_serror(cbb);
1751 
1752 	tegra234_cbb_error_enable(&cbb->base);
1753 
1754 	dev_dbg(dev, "%s resumed\n", cbb->fabric->fab_list[cbb->fabric->fab_id].name);
1755 
1756 	return 0;
1757 }
1758 
1759 static const struct dev_pm_ops tegra234_cbb_pm = {
1760 	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, tegra234_cbb_resume_noirq)
1761 };
1762 
1763 static struct platform_driver tegra234_cbb_driver = {
1764 	.probe = tegra234_cbb_probe,
1765 	.driver = {
1766 		.name = "tegra234-cbb",
1767 		.of_match_table = tegra234_cbb_dt_ids,
1768 		.acpi_match_table = tegra241_cbb_acpi_ids,
1769 		.pm = &tegra234_cbb_pm,
1770 	},
1771 };
1772 
1773 static int __init tegra234_cbb_init(void)
1774 {
1775 	return platform_driver_register(&tegra234_cbb_driver);
1776 }
1777 pure_initcall(tegra234_cbb_init);
1778 
1779 static void __exit tegra234_cbb_exit(void)
1780 {
1781 	platform_driver_unregister(&tegra234_cbb_driver);
1782 }
1783 module_exit(tegra234_cbb_exit);
1784 
1785 MODULE_DESCRIPTION("Control Backbone 2.0 error handling driver for Tegra234");
1786