2 * Copyright 2008-2011 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: GPL-2.0+
9 #include <fdt_support.h>
11 #include <asm/immap_85xx.h>
13 #include <asm/processor.h>
14 #include <asm/fsl_portals.h>
15 #include <asm/fsl_liodn.h>
17 int get_dpaa_liodn(enum fsl_dpaa_dev dpaa_dev
, u32
*liodns
, int liodn_offset
)
19 liodns
[0] = liodn_bases
[dpaa_dev
].id
[0] + liodn_offset
;
21 if (liodn_bases
[dpaa_dev
].num_ids
== 2)
22 liodns
[1] = liodn_bases
[dpaa_dev
].id
[1] + liodn_offset
;
24 return liodn_bases
[dpaa_dev
].num_ids
;
27 #ifdef CONFIG_SYS_SRIO
28 static void set_srio_liodn(struct srio_liodn_id_table
*tbl
, int size
)
32 for (i
= 0; i
< size
; i
++) {
33 unsigned long reg_off
= tbl
[i
].reg_offset
[0];
34 out_be32((u32
*)reg_off
, tbl
[i
].id
[0]);
36 if (tbl
[i
].num_ids
== 2) {
37 reg_off
= tbl
[i
].reg_offset
[1];
38 out_be32((u32
*)reg_off
, tbl
[i
].id
[1]);
44 static void set_liodn(struct liodn_id_table
*tbl
, int size
)
48 for (i
= 0; i
< size
; i
++) {
50 if (tbl
[i
].num_ids
== 2) {
51 liodn
= (tbl
[i
].id
[0] << 16) | tbl
[i
].id
[1];
56 out_be32((volatile u32
*)(tbl
[i
].reg_offset
), liodn
);
60 static void setup_sec_liodn_base(void)
62 ccsr_sec_t
*sec
= (void *)CONFIG_SYS_FSL_SEC_ADDR
;
65 if (!IS_E_PROCESSOR(get_svr()))
69 sec_out32(&sec
->qilcr_ms
, 0x3ff<<16);
71 base
= (liodn_bases
[FSL_HW_PORTAL_SEC
].id
[0] << 16) |
72 liodn_bases
[FSL_HW_PORTAL_SEC
].id
[1];
74 sec_out32(&sec
->qilcr_ls
, base
);
77 #ifdef CONFIG_SYS_DPAA_FMAN
78 static void setup_fman_liodn_base(enum fsl_dpaa_dev dev
,
79 struct liodn_id_table
*tbl
, int size
)
86 case FSL_HW_PORTAL_FMAN1
:
87 fm
= (void *)CONFIG_SYS_FSL_FM1_ADDR
;
90 #if (CONFIG_SYS_NUM_FMAN == 2)
91 case FSL_HW_PORTAL_FMAN2
:
92 fm
= (void *)CONFIG_SYS_FSL_FM2_ADDR
;
96 printf("Error: Invalid device type to %s\n", __FUNCTION__
);
100 base
= (liodn_bases
[dev
].id
[0] << 16) | liodn_bases
[dev
].id
[0];
102 /* setup all bases the same */
103 for (i
= 0; i
< 32; i
++) {
104 out_be32(&fm
->fm_dma
.fmdmplr
[i
], base
);
107 /* update tbl to ... */
108 for (i
= 0; i
< size
; i
++)
109 tbl
[i
].id
[0] += liodn_bases
[dev
].id
[0];
113 static void setup_pme_liodn_base(void)
115 #ifdef CONFIG_SYS_DPAA_PME
116 ccsr_pme_t
*pme
= (void *)CONFIG_SYS_FSL_CORENET_PME_ADDR
;
117 u32 base
= (liodn_bases
[FSL_HW_PORTAL_PME
].id
[0] << 16) |
118 liodn_bases
[FSL_HW_PORTAL_PME
].id
[1];
120 out_be32(&pme
->liodnbr
, base
);
124 #ifdef CONFIG_SYS_FSL_RAID_ENGINE
125 static void setup_raide_liodn_base(void)
127 struct ccsr_raide
*raide
= (void *)CONFIG_SYS_FSL_RAID_ENGINE_ADDR
;
129 /* setup raid engine liodn base for data/desc ; both set to 47 */
130 u32 base
= (liodn_bases
[FSL_HW_PORTAL_RAID_ENGINE
].id
[0] << 16) |
131 liodn_bases
[FSL_HW_PORTAL_RAID_ENGINE
].id
[0];
133 out_be32(&raide
->liodnbr
, base
);
137 #ifdef CONFIG_SYS_DPAA_RMAN
138 static void set_rman_liodn(struct liodn_id_table
*tbl
, int size
)
141 struct ccsr_rman
*rman
= (void *)CONFIG_SYS_FSL_CORENET_RMAN_ADDR
;
143 for (i
= 0; i
< size
; i
++) {
144 /* write the RMan block number */
145 out_be32(&rman
->mmitar
, i
);
146 /* write the liodn offset corresponding to the block */
147 out_be32((u32
*)(tbl
[i
].reg_offset
), tbl
[i
].id
[0]);
151 static void setup_rman_liodn_base(struct liodn_id_table
*tbl
, int size
)
154 struct ccsr_rman
*rman
= (void *)CONFIG_SYS_FSL_CORENET_RMAN_ADDR
;
155 u32 base
= liodn_bases
[FSL_HW_PORTAL_RMAN
].id
[0];
157 out_be32(&rman
->mmliodnbr
, base
);
159 /* update liodn offset */
160 for (i
= 0; i
< size
; i
++)
161 tbl
[i
].id
[0] += base
;
165 void set_liodns(void)
167 /* setup general liodn offsets */
168 set_liodn(liodn_tbl
, liodn_tbl_sz
);
170 #ifdef CONFIG_SYS_SRIO
171 /* setup SRIO port liodns */
172 set_srio_liodn(srio_liodn_tbl
, srio_liodn_tbl_sz
);
175 /* setup SEC block liodn bases & offsets if we have one */
176 if (IS_E_PROCESSOR(get_svr())) {
177 set_liodn(sec_liodn_tbl
, sec_liodn_tbl_sz
);
178 setup_sec_liodn_base();
181 /* setup FMAN block(s) liodn bases & offsets if we have one */
182 #ifdef CONFIG_SYS_DPAA_FMAN
183 set_liodn(fman1_liodn_tbl
, fman1_liodn_tbl_sz
);
184 setup_fman_liodn_base(FSL_HW_PORTAL_FMAN1
, fman1_liodn_tbl
,
187 #if (CONFIG_SYS_NUM_FMAN == 2)
188 set_liodn(fman2_liodn_tbl
, fman2_liodn_tbl_sz
);
189 setup_fman_liodn_base(FSL_HW_PORTAL_FMAN2
, fman2_liodn_tbl
,
193 /* setup PME liodn base */
194 setup_pme_liodn_base();
196 #ifdef CONFIG_SYS_FSL_RAID_ENGINE
197 /* raid engine ccr addr code for liodn */
198 set_liodn(raide_liodn_tbl
, raide_liodn_tbl_sz
);
199 setup_raide_liodn_base();
202 #ifdef CONFIG_SYS_DPAA_RMAN
203 /* setup RMan liodn offsets */
204 set_rman_liodn(rman_liodn_tbl
, rman_liodn_tbl_sz
);
205 /* setup RMan liodn base */
206 setup_rman_liodn_base(rman_liodn_tbl
, rman_liodn_tbl_sz
);
210 #ifdef CONFIG_SYS_SRIO
211 static void fdt_fixup_srio_liodn(void *blob
, struct srio_liodn_id_table
*tbl
)
215 /* search for srio node, if doesn't exist just return - nothing todo */
216 srio_off
= fdt_node_offset_by_compatible(blob
, -1, "fsl,srio");
220 for (i
= 0; i
< srio_liodn_tbl_sz
; i
++) {
221 int off
, portid
= tbl
[i
].portid
;
223 off
= fdt_node_offset_by_prop_value(blob
, srio_off
,
224 "cell-index", &portid
, 4);
226 off
= fdt_setprop(blob
, off
, "fsl,liodn",
228 sizeof(u32
) * tbl
[i
].num_ids
);
230 printf("WARNING unable to set fsl,liodn for "
231 "fsl,srio port %d: %s\n",
232 portid
, fdt_strerror(off
));
234 debug("WARNING: couldn't set fsl,liodn for srio: %s.\n",
241 #define CONFIG_SYS_MAX_PCI_EPS 8
243 static void fdt_fixup_pci_liodn_offsets(void *fdt
, const char *compat
,
246 int off
, pci_idx
= 0, pci_cnt
= 0, i
, rc
;
247 const uint32_t *base_liodn
;
248 uint32_t liodn_offs
[CONFIG_SYS_MAX_PCI_EPS
+ 1] = { 0 };
251 * Count the number of pci nodes.
252 * It's needed later when the interleaved liodn offsets are generated.
254 off
= fdt_node_offset_by_compatible(fdt
, -1, compat
);
255 while (off
!= -FDT_ERR_NOTFOUND
) {
257 off
= fdt_node_offset_by_compatible(fdt
, off
, compat
);
260 for (off
= fdt_node_offset_by_compatible(fdt
, -1, compat
);
261 off
!= -FDT_ERR_NOTFOUND
;
262 off
= fdt_node_offset_by_compatible(fdt
, off
, compat
)) {
263 base_liodn
= fdt_getprop(fdt
, off
, "fsl,liodn", &rc
);
267 if (fdt_get_path(fdt
, off
, path
, sizeof(path
)) < 0)
268 strcpy(path
, "(unknown)");
269 printf("WARNING Could not get liodn of node %s: %s\n",
270 path
, fdt_strerror(rc
));
273 for (i
= 0; i
< CONFIG_SYS_MAX_PCI_EPS
; i
++)
274 liodn_offs
[i
+ 1] = ep_liodn_start
+
275 i
* pci_cnt
+ pci_idx
- *base_liodn
;
276 rc
= fdt_setprop(fdt
, off
, "fsl,liodn-offset-list",
277 liodn_offs
, sizeof(liodn_offs
));
281 if (fdt_get_path(fdt
, off
, path
, sizeof(path
)) < 0)
282 strcpy(path
, "(unknown)");
283 printf("WARNING Unable to set fsl,liodn-offset-list for "
284 "node %s: %s\n", path
, fdt_strerror(rc
));
291 static void fdt_fixup_liodn_tbl(void *blob
, struct liodn_id_table
*tbl
, int sz
)
295 for (i
= 0; i
< sz
; i
++) {
298 if (tbl
[i
].compat
== NULL
)
301 off
= fdt_node_offset_by_compat_reg(blob
,
302 tbl
[i
].compat
, tbl
[i
].compat_offset
);
304 off
= fdt_setprop(blob
, off
, "fsl,liodn",
306 sizeof(u32
) * tbl
[i
].num_ids
);
308 printf("WARNING unable to set fsl,liodn for "
310 tbl
[i
].compat
, fdt_strerror(off
));
312 debug("WARNING: could not set fsl,liodn for %s: %s.\n",
313 tbl
[i
].compat
, fdt_strerror(off
));
318 void fdt_fixup_liodn(void *blob
)
320 #ifdef CONFIG_SYS_SRIO
321 fdt_fixup_srio_liodn(blob
, srio_liodn_tbl
);
324 fdt_fixup_liodn_tbl(blob
, liodn_tbl
, liodn_tbl_sz
);
325 #ifdef CONFIG_SYS_DPAA_FMAN
326 fdt_fixup_liodn_tbl(blob
, fman1_liodn_tbl
, fman1_liodn_tbl_sz
);
327 #if (CONFIG_SYS_NUM_FMAN == 2)
328 fdt_fixup_liodn_tbl(blob
, fman2_liodn_tbl
, fman2_liodn_tbl_sz
);
331 fdt_fixup_liodn_tbl(blob
, sec_liodn_tbl
, sec_liodn_tbl_sz
);
333 #ifdef CONFIG_SYS_FSL_RAID_ENGINE
334 fdt_fixup_liodn_tbl(blob
, raide_liodn_tbl
, raide_liodn_tbl_sz
);
337 #ifdef CONFIG_SYS_DPAA_RMAN
338 fdt_fixup_liodn_tbl(blob
, rman_liodn_tbl
, rman_liodn_tbl_sz
);
341 ccsr_pcix_t
*pcix
= (ccsr_pcix_t
*)CONFIG_SYS_PCIE1_ADDR
;
342 int pci_ver
= pcix
->ipver1
& 0xffff, liodn_base
= 0;
344 if (pci_ver
>= 0x0204) {
345 if (pci_ver
>= 0x0300)
354 sprintf(compat
, "fsl,qoriq-pcie-v%d.%d",
355 (pci_ver
& 0xff00) >> 8, pci_ver
& 0xff);
356 fdt_fixup_pci_liodn_offsets(blob
, compat
, liodn_base
);
357 fdt_fixup_pci_liodn_offsets(blob
, "fsl,qoriq-pcie", liodn_base
);