blob: d529095ee8c2884fee16508097fa753c6b8e0b62 [file] [log] [blame]
Kumar Gala38449a42009-09-10 03:02:13 -05001/*
Haiying Wang325a12f2011-01-20 22:26:31 +00002 * Copyright 2008-2011 Freescale Semiconductor, Inc.
Kumar Gala38449a42009-09-10 03:02:13 -05003 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23#include <common.h>
24#include <libfdt.h>
25#include <fdt_support.h>
26
27#include <asm/processor.h>
28#include <asm/io.h>
29
30#include <asm/fsl_portals.h>
31#include <asm/fsl_liodn.h>
32
Kumar Gala38449a42009-09-10 03:02:13 -050033void setup_portals(void)
34{
Jeffrey Ladouceur13452202013-01-25 10:38:53 +000035 ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
Haiying Wang325a12f2011-01-20 22:26:31 +000036#ifdef CONFIG_FSL_CORENET
Kumar Gala38449a42009-09-10 03:02:13 -050037 int i;
38
Kumar Gala38449a42009-09-10 03:02:13 -050039 for (i = 0; i < CONFIG_SYS_QMAN_NUM_PORTALS; i++) {
40 u8 sdest = qp_info[i].sdest;
41 u16 fliodn = qp_info[i].fliodn;
42 u16 dliodn = qp_info[i].dliodn;
43 u16 liodn_off = qp_info[i].liodn_offset;
44
45 out_be32(&qman->qcsp[i].qcsp_lio_cfg, (liodn_off << 16) |
46 dliodn);
47 /* set frame liodn */
48 out_be32(&qman->qcsp[i].qcsp_io_cfg, (sdest << 16) | fliodn);
49 }
Haiying Wang325a12f2011-01-20 22:26:31 +000050#endif
51
52 /* Set the Qman initiator BAR to match the LAW (for DQRR stashing) */
53#ifdef CONFIG_PHYS_64BIT
54 out_be32(&qman->qcsp_bare, (u32)(CONFIG_SYS_QMAN_MEM_PHYS >> 32));
55#endif
56 out_be32(&qman->qcsp_bar, (u32)CONFIG_SYS_QMAN_MEM_PHYS);
Kumar Gala38449a42009-09-10 03:02:13 -050057}
58
59/* Update portal containter to match LAW setup of portal in phy map */
60void fdt_portal(void *blob, const char *compat, const char *container,
61 u64 addr, u32 size)
62{
63 int off;
64
65 off = fdt_node_offset_by_compatible(blob, -1, compat);
66 if (off < 0)
67 return ;
68
69 off = fdt_parent_offset(blob, off);
70 /* if non-zero assume we have a container */
71 if (off > 0) {
72 char buf[60];
73 const char *p, *name;
74 u32 *range;
75 int len;
76
77 /* fixup ranges */
78 range = fdt_getprop_w(blob, off, "ranges", &len);
79 if (range == NULL) {
80 printf("ERROR: container for %s has no ranges", compat);
81 return ;
82 }
83
84 range[0] = 0;
85 if (len == 16) {
86 range[1] = addr >> 32;
87 range[2] = addr & 0xffffffff;
88 range[3] = size;
89 } else {
90 range[1] = addr & 0xffffffff;
91 range[2] = size;
92 }
93 fdt_setprop_inplace(blob, off, "ranges", range, len);
94
95 /* fixup the name */
96 name = fdt_get_name(blob, off, &len);
97 p = memchr(name, '@', len);
98
99 if (p)
100 len = p - name;
101
102 /* if we are given a container name check it
103 * against what we found, if it doesnt match exit out */
104 if (container && (memcmp(container, name, len))) {
105 printf("WARNING: container names didn't match %s %s\n",
106 container, name);
107 return ;
108 }
109
110 memcpy(&buf, name, len);
111 len += sprintf(&buf[len], "@%llx", addr);
112 fdt_set_name(blob, off, buf);
113 return ;
114 }
115
116 printf("ERROR: %s isn't in a container. Not supported\n", compat);
117}
118
119static int fdt_qportal(void *blob, int off, int id, char *name,
120 enum fsl_dpaa_dev dev, int create)
121{
Haiying Wang325a12f2011-01-20 22:26:31 +0000122 int childoff, dev_off, ret = 0;
Kumar Gala38449a42009-09-10 03:02:13 -0500123 uint32_t dev_handle;
Haiying Wang325a12f2011-01-20 22:26:31 +0000124#ifdef CONFIG_FSL_CORENET
125 int num;
Kumar Gala38449a42009-09-10 03:02:13 -0500126 u32 liodns[2];
Haiying Wang325a12f2011-01-20 22:26:31 +0000127#endif
Kumar Gala38449a42009-09-10 03:02:13 -0500128
129 childoff = fdt_subnode_offset(blob, off, name);
130 if (create) {
131 if (childoff <= 0)
132 childoff = fdt_add_subnode(blob, off, name);
133
134 if (childoff > 0) {
135 char handle[64], *p;
136
137 strncpy(handle, name, sizeof(handle));
138 p = strchr(handle, '@');
139 if (!strncmp(name, "fman", 4)) {
140 *p = *(p + 1);
141 p++;
142 }
143 *p = '\0';
144
145 dev_off = fdt_path_offset(blob, handle);
146 if (dev_off < 0)
147 return dev_off;
148
149 dev_handle = fdt_get_phandle(blob, dev_off);
150 if (dev_handle <= 0) {
151 dev_handle = fdt_alloc_phandle(blob);
Kumar Galaf2f1c5a2011-08-01 00:23:23 -0500152 ret = fdt_set_phandle(blob, dev_off,
Timur Tabiecd9c692011-05-10 15:28:14 -0500153 dev_handle);
154 if (ret < 0)
155 return ret;
Kumar Gala38449a42009-09-10 03:02:13 -0500156 }
157
158 ret = fdt_setprop(blob, childoff, "dev-handle",
159 &dev_handle, sizeof(dev_handle));
160 if (ret < 0)
161 return ret;
162
Haiying Wang325a12f2011-01-20 22:26:31 +0000163#ifdef CONFIG_FSL_CORENET
Kumar Gala38449a42009-09-10 03:02:13 -0500164 num = get_dpaa_liodn(dev, &liodns[0], id);
165 ret = fdt_setprop(blob, childoff, "fsl,liodn",
166 &liodns[0], sizeof(u32) * num);
Jeffrey Ladouceur13452202013-01-25 10:38:53 +0000167 if (!strncmp(name, "pme", 3)) {
168 u32 pme_rev1, pme_rev2;
169 ccsr_pme_t *pme_regs =
170 (void *)CONFIG_SYS_FSL_CORENET_PME_ADDR;
171
172 pme_rev1 = in_be32(&pme_regs->pm_ip_rev_1);
173 pme_rev2 = in_be32(&pme_regs->pm_ip_rev_2);
174 ret = fdt_setprop(blob, childoff,
175 "fsl,pme-rev1", &pme_rev1, sizeof(u32));
176 if (ret < 0)
177 return ret;
178 ret = fdt_setprop(blob, childoff,
179 "fsl,pme-rev2", &pme_rev2, sizeof(u32));
180 }
Haiying Wang325a12f2011-01-20 22:26:31 +0000181#endif
Kumar Gala38449a42009-09-10 03:02:13 -0500182 } else {
183 return childoff;
184 }
185 } else {
186 if (childoff > 0)
187 ret = fdt_del_node(blob, childoff);
188 }
189
190 return ret;
191}
192
193void fdt_fixup_qportals(void *blob)
194{
195 int off, err;
196 unsigned int maj, min;
Haiying Wange67bdfc2012-10-11 07:13:38 +0000197 unsigned int ip_cfg;
Jeffrey Ladouceur13452202013-01-25 10:38:53 +0000198 ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
Kumar Gala38449a42009-09-10 03:02:13 -0500199 u32 rev_1 = in_be32(&qman->ip_rev_1);
Haiying Wange67bdfc2012-10-11 07:13:38 +0000200 u32 rev_2 = in_be32(&qman->ip_rev_2);
Kumar Gala38449a42009-09-10 03:02:13 -0500201 char compat[64];
202 int compat_len;
203
204 maj = (rev_1 >> 8) & 0xff;
205 min = rev_1 & 0xff;
Haiying Wange67bdfc2012-10-11 07:13:38 +0000206 ip_cfg = rev_2 & 0xff;
Kumar Gala38449a42009-09-10 03:02:13 -0500207
Haiying Wange67bdfc2012-10-11 07:13:38 +0000208 compat_len = sprintf(compat, "fsl,qman-portal-%u.%u.%u",
209 maj, min, ip_cfg) + 1;
Kumar Gala38449a42009-09-10 03:02:13 -0500210 compat_len += sprintf(compat + compat_len, "fsl,qman-portal") + 1;
211
212 off = fdt_node_offset_by_compatible(blob, -1, "fsl,qman-portal");
213 while (off != -FDT_ERR_NOTFOUND) {
Haiying Wang325a12f2011-01-20 22:26:31 +0000214#ifdef CONFIG_FSL_CORENET
Kumar Gala38449a42009-09-10 03:02:13 -0500215 u32 liodns[2];
Haiying Wang325a12f2011-01-20 22:26:31 +0000216#endif
Kumar Gala38449a42009-09-10 03:02:13 -0500217 const int *ci = fdt_getprop(blob, off, "cell-index", NULL);
Kumar Gala302a65c2011-07-31 12:55:39 -0500218 int i = *ci;
219#ifdef CONFIG_SYS_DPAA_FMAN
220 int j;
221#endif
Kumar Gala38449a42009-09-10 03:02:13 -0500222
223 err = fdt_setprop(blob, off, "compatible", compat, compat_len);
224 if (err < 0)
225 goto err;
226
Haiying Wang325a12f2011-01-20 22:26:31 +0000227#ifdef CONFIG_FSL_CORENET
Kumar Gala38449a42009-09-10 03:02:13 -0500228 liodns[0] = qp_info[i].dliodn;
229 liodns[1] = qp_info[i].fliodn;
230
231 err = fdt_setprop(blob, off, "fsl,liodn",
232 &liodns, sizeof(u32) * 2);
233 if (err < 0)
234 goto err;
Haiying Wang325a12f2011-01-20 22:26:31 +0000235#endif
Kumar Gala38449a42009-09-10 03:02:13 -0500236
237 i++;
238
239 err = fdt_qportal(blob, off, i, "crypto@0", FSL_HW_PORTAL_SEC,
240 IS_E_PROCESSOR(get_svr()));
241 if (err < 0)
242 goto err;
243
Haiying Wang325a12f2011-01-20 22:26:31 +0000244#ifdef CONFIG_FSL_CORENET
Kumar Gala38449a42009-09-10 03:02:13 -0500245#ifdef CONFIG_SYS_DPAA_PME
246 err = fdt_qportal(blob, off, i, "pme@0", FSL_HW_PORTAL_PME, 1);
247 if (err < 0)
248 goto err;
249#else
250 fdt_qportal(blob, off, i, "pme@0", FSL_HW_PORTAL_PME, 0);
251#endif
Haiying Wang325a12f2011-01-20 22:26:31 +0000252#endif
253
Kumar Gala38449a42009-09-10 03:02:13 -0500254#ifdef CONFIG_SYS_DPAA_FMAN
255 for (j = 0; j < CONFIG_SYS_NUM_FMAN; j++) {
256 char name[] = "fman@0";
257
258 name[sizeof(name) - 2] = '0' + j;
259 err = fdt_qportal(blob, off, i, name,
260 FSL_HW_PORTAL_FMAN1 + j, 1);
261 if (err < 0)
262 goto err;
263 }
264#endif
Kumar Gala4eb3c372011-10-14 13:28:52 -0500265#ifdef CONFIG_SYS_DPAA_RMAN
266 err = fdt_qportal(blob, off, i, "rman@0",
267 FSL_HW_PORTAL_RMAN, 1);
268 if (err < 0)
269 goto err;
270#endif
Kumar Gala38449a42009-09-10 03:02:13 -0500271
272err:
273 if (err < 0) {
274 printf("ERROR: unable to create props for %s: %s\n",
275 fdt_get_name(blob, off, NULL), fdt_strerror(err));
276 return;
277 }
278
279 off = fdt_node_offset_by_compatible(blob, off, "fsl,qman-portal");
280 }
281}
Haiying Wangd38d4b22011-03-01 09:30:07 -0500282
283void fdt_fixup_bportals(void *blob)
284{
285 int off, err;
286 unsigned int maj, min;
Haiying Wange67bdfc2012-10-11 07:13:38 +0000287 unsigned int ip_cfg;
Jeffrey Ladouceur13452202013-01-25 10:38:53 +0000288 ccsr_bman_t *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR;
Haiying Wangd38d4b22011-03-01 09:30:07 -0500289 u32 rev_1 = in_be32(&bman->ip_rev_1);
Haiying Wange67bdfc2012-10-11 07:13:38 +0000290 u32 rev_2 = in_be32(&bman->ip_rev_2);
Haiying Wangd38d4b22011-03-01 09:30:07 -0500291 char compat[64];
292 int compat_len;
293
294 maj = (rev_1 >> 8) & 0xff;
295 min = rev_1 & 0xff;
296
Haiying Wange67bdfc2012-10-11 07:13:38 +0000297 ip_cfg = rev_2 & 0xff;
298
299 compat_len = sprintf(compat, "fsl,bman-portal-%u.%u.%u",
300 maj, min, ip_cfg) + 1;
Haiying Wangd38d4b22011-03-01 09:30:07 -0500301 compat_len += sprintf(compat + compat_len, "fsl,bman-portal") + 1;
302
303 off = fdt_node_offset_by_compatible(blob, -1, "fsl,bman-portal");
304 while (off != -FDT_ERR_NOTFOUND) {
305 err = fdt_setprop(blob, off, "compatible", compat, compat_len);
306 if (err < 0) {
307 printf("ERROR: unable to create props for %s: %s\n",
308 fdt_get_name(blob, off, NULL),
309 fdt_strerror(err));
310 return;
311 }
312
313 off = fdt_node_offset_by_compatible(blob, off, "fsl,bman-portal");
314 }
315
316}