diff options
Diffstat (limited to 'arch/powerpc/cpu/mpc85xx/liodn.c')
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/liodn.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/arch/powerpc/cpu/mpc85xx/liodn.c b/arch/powerpc/cpu/mpc85xx/liodn.c index e0ea502..11881c9 100644 --- a/arch/powerpc/cpu/mpc85xx/liodn.c +++ b/arch/powerpc/cpu/mpc85xx/liodn.c @@ -40,6 +40,21 @@ int get_dpaa_liodn(enum fsl_dpaa_dev dpaa_dev, u32 *liodns, int liodn_offset) return liodn_bases[dpaa_dev].num_ids; } +static void set_srio_liodn(struct srio_liodn_id_table *tbl, int size) +{ + int i; + + for (i = 0; i < size; i++) { + unsigned long reg_off = tbl[i].reg_offset[0]; + out_be32((u32 *)reg_off, tbl[i].id[0]); + + if (tbl[i].num_ids == 2) { + reg_off = tbl[i].reg_offset[1]; + out_be32((u32 *)reg_off, tbl[i].id[1]); + } + } +} + static void set_liodn(struct liodn_id_table *tbl, int size) { int i; @@ -133,11 +148,42 @@ static void setup_raide_liodn_base(void) } #endif +#ifdef CONFIG_SYS_DPAA_RMAN +static void set_rman_liodn(struct liodn_id_table *tbl, int size) +{ + int i; + struct ccsr_rman *rman = (void *)CONFIG_SYS_FSL_CORENET_RMAN_ADDR; + + for (i = 0; i < size; i++) { + /* write the RMan block number */ + out_be32(&rman->mmitar, i); + /* write the liodn offset corresponding to the block */ + out_be32((u32 *)(tbl[i].reg_offset), tbl[i].id[0]); + } +} + +static void setup_rman_liodn_base(struct liodn_id_table *tbl, int size) +{ + int i; + struct ccsr_rman *rman = (void *)CONFIG_SYS_FSL_CORENET_RMAN_ADDR; + u32 base = liodn_bases[FSL_HW_PORTAL_RMAN].id[0]; + + out_be32(&rman->mmliodnbr, base); + + /* update liodn offset */ + for (i = 0; i < size; i++) + tbl[i].id[0] += base; +} +#endif + void set_liodns(void) { /* setup general liodn offsets */ set_liodn(liodn_tbl, liodn_tbl_sz); + /* setup SRIO port liodns */ + set_srio_liodn(srio_liodn_tbl, srio_liodn_tbl_sz); + /* setup SEC block liodn bases & offsets if we have one */ if (IS_E_PROCESSOR(get_svr())) { set_liodn(sec_liodn_tbl, sec_liodn_tbl_sz); @@ -164,6 +210,42 @@ void set_liodns(void) set_liodn(raide_liodn_tbl, raide_liodn_tbl_sz); setup_raide_liodn_base(); #endif + +#ifdef CONFIG_SYS_DPAA_RMAN + /* setup RMan liodn offsets */ + set_rman_liodn(rman_liodn_tbl, rman_liodn_tbl_sz); + /* setup RMan liodn base */ + setup_rman_liodn_base(rman_liodn_tbl, rman_liodn_tbl_sz); +#endif +} + +static void fdt_fixup_srio_liodn(void *blob, struct srio_liodn_id_table *tbl) +{ + int i, srio_off; + + /* search for srio node, if doesn't exist just return - nothing todo */ + srio_off = fdt_node_offset_by_compatible(blob, -1, "fsl,srio"); + if (srio_off < 0) + return ; + + for (i = 0; i < srio_liodn_tbl_sz; i++) { + int off, portid = tbl[i].portid; + + off = fdt_node_offset_by_prop_value(blob, srio_off, + "cell-index", &portid, 4); + if (off >= 0) { + off = fdt_setprop(blob, off, "fsl,liodn", + &tbl[i].id[0], + sizeof(u32) * tbl[i].num_ids); + if (off > 0) + printf("WARNING unable to set fsl,liodn for " + "fsl,srio port %d: %s\n", + portid, fdt_strerror(off)); + } else { + debug("WARNING: couldn't set fsl,liodn for srio: %s.\n", + fdt_strerror(off)); + } + } } static void fdt_fixup_liodn_tbl(void *blob, struct liodn_id_table *tbl, int sz) @@ -195,6 +277,8 @@ static void fdt_fixup_liodn_tbl(void *blob, struct liodn_id_table *tbl, int sz) void fdt_fixup_liodn(void *blob) { + fdt_fixup_srio_liodn(blob, srio_liodn_tbl); + fdt_fixup_liodn_tbl(blob, liodn_tbl, liodn_tbl_sz); #ifdef CONFIG_SYS_DPAA_FMAN fdt_fixup_liodn_tbl(blob, fman1_liodn_tbl, fman1_liodn_tbl_sz); @@ -207,4 +291,8 @@ void fdt_fixup_liodn(void *blob) #ifdef CONFIG_SYS_FSL_RAID_ENGINE fdt_fixup_liodn_tbl(blob, raide_liodn_tbl, raide_liodn_tbl_sz); #endif + +#ifdef CONFIG_SYS_DPAA_RMAN + fdt_fixup_liodn_tbl(blob, rman_liodn_tbl, rman_liodn_tbl_sz); +#endif } |