1 // SPDX-License-Identifier: GPL-2.0+
7 #include <linux/libfdt.h>
8 #include <fdt_support.h>
11 #include <asm/processor.h>
12 #include <asm/arch-fsl-layerscape/fsl_icid.h>
15 static void set_icid(struct icid_id_table *tbl, int size)
19 for (i = 0; i < size; i++)
21 out_le32((u32 *)(tbl[i].reg_addr), tbl[i].reg);
23 out_be32((u32 *)(tbl[i].reg_addr), tbl[i].reg);
26 #ifdef CONFIG_SYS_DPAA_FMAN
27 void set_fman_icids(struct fman_icid_id_table *tbl, int size)
30 ccsr_fman_t *fm = (void *)CFG_SYS_FSL_FM1_ADDR;
32 for (i = 0; i < size; i++) {
33 out_be32(&fm->fm_bmi_common.fmbm_ppid[tbl[i].port_id - 1],
41 /* setup general icid offsets */
42 set_icid(icid_tbl, icid_tbl_sz);
44 #if defined(CONFIG_SYS_DPAA_FMAN) && !defined(CONFIG_SPL_BUILD)
45 set_fman_icids(fman_icid_tbl, fman_icid_tbl_sz);
49 #ifndef CONFIG_SPL_BUILD
50 int fdt_set_iommu_prop(void *blob, int off, int smmu_ph, u32 *ids, int num_ids)
56 * Note: The "iommus" property definition mentions Stream IDs while
57 * this code handles ICIDs. The current implementation assumes that
58 * ICIDs and Stream IDs are equal.
60 for (i = 0; i < num_ids; i++) {
61 prop[i * 2] = cpu_to_fdt32(smmu_ph);
62 prop[i * 2 + 1] = cpu_to_fdt32(ids[i]);
64 ret = fdt_setprop(blob, off, "iommus",
65 prop, sizeof(u32) * num_ids * 2);
67 printf("WARNING unable to set iommus: %s\n", fdt_strerror(ret));
74 int fdt_fixup_icid_tbl(void *blob, int smmu_ph,
75 struct icid_id_table *tbl, int size)
79 for (i = 0; i < size; i++) {
83 off = fdt_node_offset_by_compat_reg(blob,
87 err = fdt_set_iommu_prop(blob, off, smmu_ph,
92 printf("WARNING could not find node %s: %s.\n",
93 tbl[i].compat, fdt_strerror(off));
100 #ifdef CONFIG_SYS_DPAA_FMAN
101 int get_fman_port_icid(int port_id, struct fman_icid_id_table *tbl,
106 for (i = 0; i < size; i++) {
107 if (tbl[i].port_id == port_id)
114 void fdt_fixup_fman_port_icid_by_compat(void *blob, int smmu_ph,
120 fdt_for_each_node_by_compatible(noff, blob, -1, compat) {
121 prop = fdt_getprop(blob, noff, "cell-index", &len);
123 printf("WARNING missing cell-index for fman port\n");
127 printf("WARNING bad cell-index size for fman port\n");
131 icid = get_fman_port_icid(fdt32_to_cpu(*prop),
132 fman_icid_tbl, fman_icid_tbl_sz);
134 printf("WARNING unknown ICID for fman port %d\n",
139 fdt_set_iommu_prop(blob, noff, smmu_ph, (u32 *)&icid, 1);
143 void fdt_fixup_fman_icids(void *blob, int smmu_ph)
145 static const char * const compats[] = {
146 "fsl,fman-v3-port-oh",
147 "fsl,fman-v3-port-rx",
148 "fsl,fman-v3-port-tx",
152 for (i = 0; i < ARRAY_SIZE(compats); i++)
153 fdt_fixup_fman_port_icid_by_compat(blob, smmu_ph, compats[i]);
157 int fdt_get_smmu_phandle(void *blob)
161 noff = fdt_node_offset_by_compatible(blob, -1, "arm,mmu-500");
163 printf("WARNING failed to get smmu node: %s\n",
168 smmu_ph = fdt_get_phandle(blob, noff);
170 smmu_ph = fdt_create_phandle(blob, noff);
172 printf("WARNING failed to get smmu phandle\n");
180 void fdt_fixup_icid(void *blob)
184 smmu_ph = fdt_get_smmu_phandle(blob);
188 fdt_fixup_icid_tbl(blob, smmu_ph, icid_tbl, icid_tbl_sz);
190 #ifdef CONFIG_SYS_DPAA_FMAN
191 fdt_fixup_fman_icids(blob, smmu_ph);