blob: 672edde455ef030cce21e95884b5a71661f8240c [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) {
York Sune2f35732013-03-25 07:33:21 +0000131 char handle[64], *p;
Kumar Gala38449a42009-09-10 03:02:13 -0500132
York Sune2f35732013-03-25 07:33:21 +0000133 strncpy(handle, name, sizeof(handle));
134 p = strchr(handle, '@');
135 if (!strncmp(name, "fman", 4)) {
136 *p = *(p + 1);
137 p++;
138 }
139 *p = '\0';
Kumar Gala38449a42009-09-10 03:02:13 -0500140
York Sune2f35732013-03-25 07:33:21 +0000141 dev_off = fdt_path_offset(blob, handle);
142 /* skip this node if alias is not found */
143 if (dev_off == -FDT_ERR_BADPATH)
144 return 0;
145 if (dev_off < 0)
146 return dev_off;
Kumar Gala38449a42009-09-10 03:02:13 -0500147
York Sune2f35732013-03-25 07:33:21 +0000148 if (childoff <= 0)
149 childoff = fdt_add_subnode(blob, off, name);
150
151 /* need to update the dev_off after adding a subnode */
152 dev_off = fdt_path_offset(blob, handle);
153 if (dev_off < 0)
154 return dev_off;
Kumar Gala38449a42009-09-10 03:02:13 -0500155
York Sune2f35732013-03-25 07:33:21 +0000156 if (childoff > 0) {
Kumar Gala38449a42009-09-10 03:02:13 -0500157 dev_handle = fdt_get_phandle(blob, dev_off);
158 if (dev_handle <= 0) {
159 dev_handle = fdt_alloc_phandle(blob);
Kumar Galaf2f1c5a2011-08-01 00:23:23 -0500160 ret = fdt_set_phandle(blob, dev_off,
Timur Tabiecd9c692011-05-10 15:28:14 -0500161 dev_handle);
162 if (ret < 0)
163 return ret;
Kumar Gala38449a42009-09-10 03:02:13 -0500164 }
165
166 ret = fdt_setprop(blob, childoff, "dev-handle",
167 &dev_handle, sizeof(dev_handle));
168 if (ret < 0)
169 return ret;
170
Haiying Wang325a12f2011-01-20 22:26:31 +0000171#ifdef CONFIG_FSL_CORENET
Kumar Gala38449a42009-09-10 03:02:13 -0500172 num = get_dpaa_liodn(dev, &liodns[0], id);
173 ret = fdt_setprop(blob, childoff, "fsl,liodn",
174 &liodns[0], sizeof(u32) * num);
Jeffrey Ladouceur13452202013-01-25 10:38:53 +0000175 if (!strncmp(name, "pme", 3)) {
176 u32 pme_rev1, pme_rev2;
177 ccsr_pme_t *pme_regs =
178 (void *)CONFIG_SYS_FSL_CORENET_PME_ADDR;
179
180 pme_rev1 = in_be32(&pme_regs->pm_ip_rev_1);
181 pme_rev2 = in_be32(&pme_regs->pm_ip_rev_2);
182 ret = fdt_setprop(blob, childoff,
183 "fsl,pme-rev1", &pme_rev1, sizeof(u32));
184 if (ret < 0)
185 return ret;
186 ret = fdt_setprop(blob, childoff,
187 "fsl,pme-rev2", &pme_rev2, sizeof(u32));
188 }
Haiying Wang325a12f2011-01-20 22:26:31 +0000189#endif
Kumar Gala38449a42009-09-10 03:02:13 -0500190 } else {
191 return childoff;
192 }
193 } else {
194 if (childoff > 0)
195 ret = fdt_del_node(blob, childoff);
196 }
197
198 return ret;
199}
200
201void fdt_fixup_qportals(void *blob)
202{
203 int off, err;
204 unsigned int maj, min;
Haiying Wange67bdfc2012-10-11 07:13:38 +0000205 unsigned int ip_cfg;
Jeffrey Ladouceur13452202013-01-25 10:38:53 +0000206 ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
Kumar Gala38449a42009-09-10 03:02:13 -0500207 u32 rev_1 = in_be32(&qman->ip_rev_1);
Haiying Wange67bdfc2012-10-11 07:13:38 +0000208 u32 rev_2 = in_be32(&qman->ip_rev_2);
Kumar Gala38449a42009-09-10 03:02:13 -0500209 char compat[64];
210 int compat_len;
211
212 maj = (rev_1 >> 8) & 0xff;
213 min = rev_1 & 0xff;
Haiying Wange67bdfc2012-10-11 07:13:38 +0000214 ip_cfg = rev_2 & 0xff;
Kumar Gala38449a42009-09-10 03:02:13 -0500215
Haiying Wange67bdfc2012-10-11 07:13:38 +0000216 compat_len = sprintf(compat, "fsl,qman-portal-%u.%u.%u",
217 maj, min, ip_cfg) + 1;
Kumar Gala38449a42009-09-10 03:02:13 -0500218 compat_len += sprintf(compat + compat_len, "fsl,qman-portal") + 1;
219
220 off = fdt_node_offset_by_compatible(blob, -1, "fsl,qman-portal");
221 while (off != -FDT_ERR_NOTFOUND) {
Haiying Wang325a12f2011-01-20 22:26:31 +0000222#ifdef CONFIG_FSL_CORENET
Kumar Gala38449a42009-09-10 03:02:13 -0500223 u32 liodns[2];
Haiying Wang325a12f2011-01-20 22:26:31 +0000224#endif
Kumar Gala38449a42009-09-10 03:02:13 -0500225 const int *ci = fdt_getprop(blob, off, "cell-index", NULL);
Kumar Gala302a65c2011-07-31 12:55:39 -0500226 int i = *ci;
227#ifdef CONFIG_SYS_DPAA_FMAN
228 int j;
229#endif
Kumar Gala38449a42009-09-10 03:02:13 -0500230
231 err = fdt_setprop(blob, off, "compatible", compat, compat_len);
232 if (err < 0)
233 goto err;
234
Haiying Wang325a12f2011-01-20 22:26:31 +0000235#ifdef CONFIG_FSL_CORENET
Kumar Gala38449a42009-09-10 03:02:13 -0500236 liodns[0] = qp_info[i].dliodn;
237 liodns[1] = qp_info[i].fliodn;
238
239 err = fdt_setprop(blob, off, "fsl,liodn",
240 &liodns, sizeof(u32) * 2);
241 if (err < 0)
242 goto err;
Haiying Wang325a12f2011-01-20 22:26:31 +0000243#endif
Kumar Gala38449a42009-09-10 03:02:13 -0500244
245 i++;
246
247 err = fdt_qportal(blob, off, i, "crypto@0", FSL_HW_PORTAL_SEC,
248 IS_E_PROCESSOR(get_svr()));
249 if (err < 0)
250 goto err;
251
Haiying Wang325a12f2011-01-20 22:26:31 +0000252#ifdef CONFIG_FSL_CORENET
Kumar Gala38449a42009-09-10 03:02:13 -0500253#ifdef CONFIG_SYS_DPAA_PME
254 err = fdt_qportal(blob, off, i, "pme@0", FSL_HW_PORTAL_PME, 1);
255 if (err < 0)
256 goto err;
257#else
258 fdt_qportal(blob, off, i, "pme@0", FSL_HW_PORTAL_PME, 0);
259#endif
Haiying Wang325a12f2011-01-20 22:26:31 +0000260#endif
261
Kumar Gala38449a42009-09-10 03:02:13 -0500262#ifdef CONFIG_SYS_DPAA_FMAN
263 for (j = 0; j < CONFIG_SYS_NUM_FMAN; j++) {
264 char name[] = "fman@0";
265
266 name[sizeof(name) - 2] = '0' + j;
267 err = fdt_qportal(blob, off, i, name,
268 FSL_HW_PORTAL_FMAN1 + j, 1);
269 if (err < 0)
270 goto err;
271 }
272#endif
Kumar Gala4eb3c372011-10-14 13:28:52 -0500273#ifdef CONFIG_SYS_DPAA_RMAN
274 err = fdt_qportal(blob, off, i, "rman@0",
275 FSL_HW_PORTAL_RMAN, 1);
276 if (err < 0)
277 goto err;
278#endif
Kumar Gala38449a42009-09-10 03:02:13 -0500279
280err:
281 if (err < 0) {
282 printf("ERROR: unable to create props for %s: %s\n",
283 fdt_get_name(blob, off, NULL), fdt_strerror(err));
284 return;
285 }
286
287 off = fdt_node_offset_by_compatible(blob, off, "fsl,qman-portal");
288 }
289}
Haiying Wangd38d4b22011-03-01 09:30:07 -0500290
291void fdt_fixup_bportals(void *blob)
292{
293 int off, err;
294 unsigned int maj, min;
Haiying Wange67bdfc2012-10-11 07:13:38 +0000295 unsigned int ip_cfg;
Jeffrey Ladouceur13452202013-01-25 10:38:53 +0000296 ccsr_bman_t *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR;
Haiying Wangd38d4b22011-03-01 09:30:07 -0500297 u32 rev_1 = in_be32(&bman->ip_rev_1);
Haiying Wange67bdfc2012-10-11 07:13:38 +0000298 u32 rev_2 = in_be32(&bman->ip_rev_2);
Haiying Wangd38d4b22011-03-01 09:30:07 -0500299 char compat[64];
300 int compat_len;
301
302 maj = (rev_1 >> 8) & 0xff;
303 min = rev_1 & 0xff;
304
Haiying Wange67bdfc2012-10-11 07:13:38 +0000305 ip_cfg = rev_2 & 0xff;
306
307 compat_len = sprintf(compat, "fsl,bman-portal-%u.%u.%u",
308 maj, min, ip_cfg) + 1;
Haiying Wangd38d4b22011-03-01 09:30:07 -0500309 compat_len += sprintf(compat + compat_len, "fsl,bman-portal") + 1;
310
311 off = fdt_node_offset_by_compatible(blob, -1, "fsl,bman-portal");
312 while (off != -FDT_ERR_NOTFOUND) {
313 err = fdt_setprop(blob, off, "compatible", compat, compat_len);
314 if (err < 0) {
315 printf("ERROR: unable to create props for %s: %s\n",
316 fdt_get_name(blob, off, NULL),
317 fdt_strerror(err));
318 return;
319 }
320
321 off = fdt_node_offset_by_compatible(blob, off, "fsl,bman-portal");
322 }
323
324}