]> git.ipfire.org Git - thirdparty/u-boot.git/blame - arch/arm/cpu/armv8/fsl-layerscape/icid.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / arch / arm / cpu / armv8 / fsl-layerscape / icid.c
CommitLineData
3cb4fe65
LT
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2018 NXP
4 */
5
d678a59d 6#include <common.h>
3cb4fe65
LT
7#include <linux/libfdt.h>
8#include <fdt_support.h>
9
10#include <asm/io.h>
11#include <asm/processor.h>
12#include <asm/arch-fsl-layerscape/fsl_icid.h>
b50ff5e1 13#include <fsl_fman.h>
3cb4fe65
LT
14
15static void set_icid(struct icid_id_table *tbl, int size)
16{
17 int i;
18
19 for (i = 0; i < size; i++)
aef654a2
LT
20 if (tbl[i].le)
21 out_le32((u32 *)(tbl[i].reg_addr), tbl[i].reg);
22 else
23 out_be32((u32 *)(tbl[i].reg_addr), tbl[i].reg);
3cb4fe65
LT
24}
25
b9112cdf
LT
26#if defined(CONFIG_SYS_DPAA_FMAN) && !defined(CONFIG_SPL_BUILD)
27static void set_fman_icids(struct fman_icid_id_table *tbl, int size)
b50ff5e1
LT
28{
29 int i;
6cc04547 30 ccsr_fman_t *fm = (void *)CFG_SYS_FSL_FM1_ADDR;
b50ff5e1
LT
31
32 for (i = 0; i < size; i++) {
33 out_be32(&fm->fm_bmi_common.fmbm_ppid[tbl[i].port_id - 1],
34 tbl[i].icid);
35 }
36}
37#endif
38
3cb4fe65
LT
39void set_icids(void)
40{
41 /* setup general icid offsets */
42 set_icid(icid_tbl, icid_tbl_sz);
b50ff5e1 43
2db82bf2 44#if defined(CONFIG_SYS_DPAA_FMAN) && !defined(CONFIG_SPL_BUILD)
b50ff5e1
LT
45 set_fman_icids(fman_icid_tbl, fman_icid_tbl_sz);
46#endif
3cb4fe65
LT
47}
48
3ed84e73 49#ifndef CONFIG_SPL_BUILD
3cb4fe65
LT
50int fdt_set_iommu_prop(void *blob, int off, int smmu_ph, u32 *ids, int num_ids)
51{
52 int i, ret;
53 u32 prop[8];
54
55 /*
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.
59 */
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]);
63 }
64 ret = fdt_setprop(blob, off, "iommus",
65 prop, sizeof(u32) * num_ids * 2);
66 if (ret) {
67 printf("WARNING unable to set iommus: %s\n", fdt_strerror(ret));
68 return ret;
69 }
70
71 return 0;
72}
73
b9112cdf 74static int fdt_fixup_icid_tbl(void *blob, int smmu_ph,
3cb4fe65
LT
75 struct icid_id_table *tbl, int size)
76{
77 int i, err, off;
78
79 for (i = 0; i < size; i++) {
80 if (!tbl[i].compat)
81 continue;
82
83 off = fdt_node_offset_by_compat_reg(blob,
84 tbl[i].compat,
85 tbl[i].compat_addr);
86 if (off > 0) {
87 err = fdt_set_iommu_prop(blob, off, smmu_ph,
88 &tbl[i].id, 1);
89 if (err)
90 return err;
91 } else {
92 printf("WARNING could not find node %s: %s.\n",
93 tbl[i].compat, fdt_strerror(off));
94 }
95 }
96
97 return 0;
98}
99
b50ff5e1 100#ifdef CONFIG_SYS_DPAA_FMAN
b9112cdf 101static int get_fman_port_icid(int port_id, struct fman_icid_id_table *tbl,
b50ff5e1
LT
102 const int size)
103{
104 int i;
105
106 for (i = 0; i < size; i++) {
107 if (tbl[i].port_id == port_id)
108 return tbl[i].icid;
109 }
110
111 return -1;
112}
113
b9112cdf 114static void fdt_fixup_fman_port_icid_by_compat(void *blob, int smmu_ph,
b50ff5e1
LT
115 const char *compat)
116{
117 int noff, len, icid;
118 const u32 *prop;
119
3058e283 120 fdt_for_each_node_by_compatible(noff, blob, -1, compat) {
b50ff5e1
LT
121 prop = fdt_getprop(blob, noff, "cell-index", &len);
122 if (!prop) {
123 printf("WARNING missing cell-index for fman port\n");
124 continue;
125 }
126 if (len != 4) {
127 printf("WARNING bad cell-index size for fman port\n");
128 continue;
129 }
130
131 icid = get_fman_port_icid(fdt32_to_cpu(*prop),
132 fman_icid_tbl, fman_icid_tbl_sz);
133 if (icid < 0) {
134 printf("WARNING unknown ICID for fman port %d\n",
135 *prop);
136 continue;
137 }
138
139 fdt_set_iommu_prop(blob, noff, smmu_ph, (u32 *)&icid, 1);
b50ff5e1
LT
140 }
141}
142
b9112cdf 143static void fdt_fixup_fman_icids(void *blob, int smmu_ph)
b50ff5e1
LT
144{
145 static const char * const compats[] = {
146 "fsl,fman-v3-port-oh",
147 "fsl,fman-v3-port-rx",
148 "fsl,fman-v3-port-tx",
149 };
150 int i;
151
152 for (i = 0; i < ARRAY_SIZE(compats); i++)
153 fdt_fixup_fman_port_icid_by_compat(blob, smmu_ph, compats[i]);
154}
155#endif
156
3cb4fe65
LT
157int fdt_get_smmu_phandle(void *blob)
158{
159 int noff, smmu_ph;
160
161 noff = fdt_node_offset_by_compatible(blob, -1, "arm,mmu-500");
162 if (noff < 0) {
163 printf("WARNING failed to get smmu node: %s\n",
164 fdt_strerror(noff));
165 return noff;
166 }
167
168 smmu_ph = fdt_get_phandle(blob, noff);
169 if (!smmu_ph) {
170 smmu_ph = fdt_create_phandle(blob, noff);
171 if (!smmu_ph) {
172 printf("WARNING failed to get smmu phandle\n");
173 return -1;
174 }
175 }
176
177 return smmu_ph;
178}
179
180void fdt_fixup_icid(void *blob)
181{
182 int smmu_ph;
183
184 smmu_ph = fdt_get_smmu_phandle(blob);
185 if (smmu_ph < 0)
186 return;
187
188 fdt_fixup_icid_tbl(blob, smmu_ph, icid_tbl, icid_tbl_sz);
b50ff5e1
LT
189
190#ifdef CONFIG_SYS_DPAA_FMAN
191 fdt_fixup_fman_icids(blob, smmu_ph);
192#endif
3cb4fe65 193}
3ed84e73 194#endif