1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2019 NXP
4  */
5 
6 #include <common.h>
7 #include <fdt_support.h>
8 #include <log.h>
9 #include <asm/arch-fsl-layerscape/immap_lsch3.h>
10 #include <asm/arch-fsl-layerscape/fsl_icid.h>
11 #include <asm/arch-fsl-layerscape/fsl_portals.h>
12 
13 struct icid_id_table icid_tbl[] = {
14 	SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
15 	SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
16 	SET_SDHC_ICID(1, FSL_SDMMC_STREAM_ID),
17 	SET_SDHC_ICID(2, FSL_SDMMC2_STREAM_ID),
18 	SET_SATA_ICID(1, "fsl,ls1028a-ahci", FSL_SATA1_STREAM_ID),
19 	SET_EDMA_ICID(FSL_EDMA_STREAM_ID),
20 	SET_QDMA_ICID("fsl,ls1028a-qdma", FSL_DMA_STREAM_ID),
21 	SET_GPU_ICID("fsl,ls1028a-gpu", FSL_GPU_STREAM_ID),
22 	SET_DISPLAY_ICID(FSL_DISPLAY_STREAM_ID),
23 #ifdef CONFIG_FSL_CAAM
24 	SET_SEC_JR_ICID_ENTRY(0, FSL_SEC_JR1_STREAM_ID),
25 	SET_SEC_JR_ICID_ENTRY(1, FSL_SEC_JR2_STREAM_ID),
26 	SET_SEC_JR_ICID_ENTRY(2, FSL_SEC_JR3_STREAM_ID),
27 	SET_SEC_JR_ICID_ENTRY(3, FSL_SEC_JR4_STREAM_ID),
28 	SET_SEC_RTIC_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
29 	SET_SEC_RTIC_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
30 	SET_SEC_RTIC_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
31 	SET_SEC_RTIC_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
32 	SET_SEC_DECO_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
33 	SET_SEC_DECO_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
34 #endif
35 };
36 
37 int icid_tbl_sz = ARRAY_SIZE(icid_tbl);
38 
39 /* integrated PCI is handled separately as it's not part of CCSR/SCFG */
40 #ifdef CONFIG_PCIE_ECAM_GENERIC
41 
42 #define ECAM_IERB_BASE		0x1f0800000ULL
43 #define ECAM_IERB_OFFSET_NA	-1
44 #define ECAM_IERB_FUNC_CNT	ARRAY_SIZE(ierb_offset)
45 /* cache related transaction attributes for PCIe functions */
46 #define ECAM_IERB_MSICAR		(ECAM_IERB_BASE + 0xa400)
47 #define ECAM_IERB_MSICAR_VALUE		0x30
48 
49 /* offset of IERB config register per PCI function */
50 static int ierb_offset[] = {
51 	0x0800,
52 	0x1800,
53 	0x2800,
54 	0x3800,
55 	0x4800,
56 	0x5800,
57 	0x6800,
58 	ECAM_IERB_OFFSET_NA,
59 	0x0804,
60 	0x0808,
61 	0x1804,
62 	0x1808,
63 };
64 
65 /*
66  * Use a custom function for LS1028A, for now this is the only SoC with IERB
67  * and we're currently considering reorganizing IERB for future SoCs.
68  */
set_ecam_icids(void)69 void set_ecam_icids(void)
70 {
71 	int i;
72 
73 	out_le32(ECAM_IERB_MSICAR, ECAM_IERB_MSICAR_VALUE);
74 
75 	for (i = 0; i < ECAM_IERB_FUNC_CNT; i++) {
76 		if (ierb_offset[i] == ECAM_IERB_OFFSET_NA)
77 			continue;
78 
79 		out_le32(ECAM_IERB_BASE + ierb_offset[i],
80 			 FSL_ECAM_STREAM_ID_START + i);
81 	}
82 }
83 
fdt_setprop_inplace_idx_u32(void * fdt,int nodeoffset,const char * name,uint32_t idx,u32 val)84 static int fdt_setprop_inplace_idx_u32(void *fdt, int nodeoffset,
85 				       const char *name, uint32_t idx, u32 val)
86 {
87 	val = cpu_to_be32(val);
88 	return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
89 						   strlen(name),
90 						   idx * sizeof(val), &val,
91 						   sizeof(val));
92 }
93 
fdt_getprop_len(void * fdt,int nodeoffset,const char * name)94 static int fdt_getprop_len(void *fdt, int nodeoffset, const char *name)
95 {
96 	int len;
97 
98 	if (fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), &len))
99 		return len;
100 
101 	return 0;
102 }
103 
fdt_fixup_ecam(void * blob)104 void fdt_fixup_ecam(void *blob)
105 {
106 	int off;
107 
108 	off = fdt_node_offset_by_compatible(blob, 0, "pci-host-ecam-generic");
109 	if (off < 0) {
110 		debug("ECAM node not found\n");
111 		return;
112 	}
113 
114 	if (fdt_getprop_len(blob, off, "msi-map") != 16 ||
115 	    fdt_getprop_len(blob, off, "iommu-map") != 16) {
116 		log_err("invalid msi/iommu-map propertly size in ECAM node\n");
117 		return;
118 	}
119 
120 	fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 2,
121 				    FSL_ECAM_STREAM_ID_START);
122 	fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 3,
123 				    ECAM_IERB_FUNC_CNT);
124 
125 	fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 2,
126 				    FSL_ECAM_STREAM_ID_START);
127 	fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 3,
128 				    ECAM_IERB_FUNC_CNT);
129 }
130 #endif /* CONFIG_PCIE_ECAM_GENERIC */
131