summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv8/fsl-layerscape/ls1028_ids.c
blob: 49df8b37900e442181ae871051e92c70d0b8bbc0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2019 NXP
 */

#include <common.h>
#include <fdt_support.h>
#include <log.h>
#include <asm/arch-fsl-layerscape/immap_lsch3.h>
#include <asm/arch-fsl-layerscape/fsl_icid.h>
#include <asm/arch-fsl-layerscape/fsl_portals.h>

struct icid_id_table icid_tbl[] = {
	SET_USB_ICID(1, "snps,dwc3", FSL_USB1_STREAM_ID),
	SET_USB_ICID(2, "snps,dwc3", FSL_USB2_STREAM_ID),
	SET_SDHC_ICID(1, FSL_SDMMC_STREAM_ID),
	SET_SDHC_ICID(2, FSL_SDMMC2_STREAM_ID),
	SET_SATA_ICID(1, "fsl,ls1028a-ahci", FSL_SATA1_STREAM_ID),
	SET_EDMA_ICID(FSL_EDMA_STREAM_ID),
	SET_QDMA_ICID("fsl,ls1028a-qdma", FSL_DMA_STREAM_ID),
	SET_GPU_ICID("fsl,ls1028a-gpu", FSL_GPU_STREAM_ID),
	SET_DISPLAY_ICID(FSL_DISPLAY_STREAM_ID),
#ifdef CONFIG_FSL_CAAM
	SET_SEC_JR_ICID_ENTRY(0, FSL_SEC_JR1_STREAM_ID),
	SET_SEC_JR_ICID_ENTRY(1, FSL_SEC_JR2_STREAM_ID),
	SET_SEC_JR_ICID_ENTRY(2, FSL_SEC_JR3_STREAM_ID),
	SET_SEC_JR_ICID_ENTRY(3, FSL_SEC_JR4_STREAM_ID),
	SET_SEC_RTIC_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
	SET_SEC_RTIC_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
	SET_SEC_RTIC_ICID_ENTRY(2, FSL_SEC_STREAM_ID),
	SET_SEC_RTIC_ICID_ENTRY(3, FSL_SEC_STREAM_ID),
	SET_SEC_DECO_ICID_ENTRY(0, FSL_SEC_STREAM_ID),
	SET_SEC_DECO_ICID_ENTRY(1, FSL_SEC_STREAM_ID),
#endif
};

int icid_tbl_sz = ARRAY_SIZE(icid_tbl);

/* integrated PCI is handled separately as it's not part of CCSR/SCFG */
#ifdef CONFIG_PCIE_ECAM_GENERIC

#define ECAM_IERB_BASE		0x1f0800000ULL
#define ECAM_IERB_OFFSET_NA	-1
#define ECAM_IERB_FUNC_CNT	ARRAY_SIZE(ierb_offset)
/* cache related transaction attributes for PCIe functions */
#define ECAM_IERB_MSICAR		(ECAM_IERB_BASE + 0xa400)
#define ECAM_IERB_MSICAR_VALUE		0x30

/* offset of IERB config register per PCI function */
static int ierb_offset[] = {
	0x0800,
	0x1800,
	0x2800,
	0x3800,
	0x4800,
	0x5800,
	0x6800,
	ECAM_IERB_OFFSET_NA,
	0x0804,
	0x0808,
	0x1804,
	0x1808,
};

/*
 * Use a custom function for LS1028A, for now this is the only SoC with IERB
 * and we're currently considering reorganizing IERB for future SoCs.
 */
void set_ecam_icids(void)
{
	int i;

	out_le32(ECAM_IERB_MSICAR, ECAM_IERB_MSICAR_VALUE);

	for (i = 0; i < ECAM_IERB_FUNC_CNT; i++) {
		if (ierb_offset[i] == ECAM_IERB_OFFSET_NA)
			continue;

		out_le32(ECAM_IERB_BASE + ierb_offset[i],
			 FSL_ECAM_STREAM_ID_START + i);
	}
}

static int fdt_setprop_inplace_idx_u32(void *fdt, int nodeoffset,
				       const char *name, uint32_t idx, u32 val)
{
	val = cpu_to_be32(val);
	return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
						   strlen(name),
						   idx * sizeof(val), &val,
						   sizeof(val));
}

static int fdt_getprop_len(void *fdt, int nodeoffset, const char *name)
{
	int len;

	if (fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), &len))
		return len;

	return 0;
}

void fdt_fixup_ecam(void *blob)
{
	int off;

	off = fdt_node_offset_by_compatible(blob, 0, "pci-host-ecam-generic");
	if (off < 0) {
		debug("ECAM node not found\n");
		return;
	}

	if (fdt_getprop_len(blob, off, "msi-map") != 16 ||
	    fdt_getprop_len(blob, off, "iommu-map") != 16) {
		log_err("invalid msi/iommu-map propertly size in ECAM node\n");
		return;
	}

	fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 2,
				    FSL_ECAM_STREAM_ID_START);
	fdt_setprop_inplace_idx_u32(blob, off, "msi-map", 3,
				    ECAM_IERB_FUNC_CNT);

	fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 2,
				    FSL_ECAM_STREAM_ID_START);
	fdt_setprop_inplace_idx_u32(blob, off, "iommu-map", 3,
				    ECAM_IERB_FUNC_CNT);
}
#endif /* CONFIG_PCIE_ECAM_GENERIC */