1db977abfSKumar Gala /* 26b3a8d00SKumar Gala * Copyright 2008-2011 Freescale Semiconductor, Inc. 3db977abfSKumar Gala * 4db977abfSKumar Gala * See file CREDITS for list of people who contributed to this 5db977abfSKumar Gala * project. 6db977abfSKumar Gala * 7db977abfSKumar Gala * This program is free software; you can redistribute it and/or 8db977abfSKumar Gala * modify it under the terms of the GNU General Public License as 9db977abfSKumar Gala * published by the Free Software Foundation; either version 2 of 10db977abfSKumar Gala * the License, or (at your option) any later version. 11db977abfSKumar Gala * 12db977abfSKumar Gala * This program is distributed in the hope that it will be useful, 13db977abfSKumar Gala * but WITHOUT ANY WARRANTY; without even the implied warranty of 14db977abfSKumar Gala * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15db977abfSKumar Gala * GNU General Public License for more details. 16db977abfSKumar Gala * 17db977abfSKumar Gala * You should have received a copy of the GNU General Public License 18db977abfSKumar Gala * along with this program; if not, write to the Free Software 19db977abfSKumar Gala * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20db977abfSKumar Gala * MA 02111-1307 USA 21db977abfSKumar Gala */ 22db977abfSKumar Gala 23db977abfSKumar Gala #include <common.h> 24db977abfSKumar Gala #include <libfdt.h> 25db977abfSKumar Gala #include <fdt_support.h> 26db977abfSKumar Gala 27db977abfSKumar Gala #include <asm/immap_85xx.h> 28db977abfSKumar Gala #include <asm/io.h> 29db977abfSKumar Gala #include <asm/processor.h> 30db977abfSKumar Gala #include <asm/fsl_portals.h> 31db977abfSKumar Gala #include <asm/fsl_liodn.h> 32db977abfSKumar Gala 33db977abfSKumar Gala int get_dpaa_liodn(enum fsl_dpaa_dev dpaa_dev, u32 *liodns, int liodn_offset) 34db977abfSKumar Gala { 35db977abfSKumar Gala liodns[0] = liodn_bases[dpaa_dev].id[0] + liodn_offset; 36db977abfSKumar Gala 37db977abfSKumar Gala if (liodn_bases[dpaa_dev].num_ids == 2) 38db977abfSKumar Gala liodns[1] = liodn_bases[dpaa_dev].id[1] + liodn_offset; 39db977abfSKumar Gala 40db977abfSKumar Gala return liodn_bases[dpaa_dev].num_ids; 41db977abfSKumar Gala } 42db977abfSKumar Gala 431a0c6421SKumar Gala static void set_srio_liodn(struct srio_liodn_id_table *tbl, int size) 441a0c6421SKumar Gala { 451a0c6421SKumar Gala int i; 461a0c6421SKumar Gala 471a0c6421SKumar Gala for (i = 0; i < size; i++) { 481a0c6421SKumar Gala unsigned long reg_off = tbl[i].reg_offset[0]; 491a0c6421SKumar Gala out_be32((u32 *)reg_off, tbl[i].id[0]); 501a0c6421SKumar Gala 511a0c6421SKumar Gala if (tbl[i].num_ids == 2) { 521a0c6421SKumar Gala reg_off = tbl[i].reg_offset[1]; 531a0c6421SKumar Gala out_be32((u32 *)reg_off, tbl[i].id[1]); 541a0c6421SKumar Gala } 551a0c6421SKumar Gala } 561a0c6421SKumar Gala } 571a0c6421SKumar Gala 58db977abfSKumar Gala static void set_liodn(struct liodn_id_table *tbl, int size) 59db977abfSKumar Gala { 60db977abfSKumar Gala int i; 61db977abfSKumar Gala 62db977abfSKumar Gala for (i = 0; i < size; i++) { 63db977abfSKumar Gala u32 liodn; 64db977abfSKumar Gala if (tbl[i].num_ids == 2) { 65db977abfSKumar Gala liodn = (tbl[i].id[0] << 16) | tbl[i].id[1]; 66db977abfSKumar Gala } else { 67db977abfSKumar Gala liodn = tbl[i].id[0]; 68db977abfSKumar Gala } 69db977abfSKumar Gala 70db977abfSKumar Gala out_be32((volatile u32 *)(tbl[i].reg_offset), liodn); 71db977abfSKumar Gala } 72db977abfSKumar Gala } 73db977abfSKumar Gala 74db977abfSKumar Gala static void setup_sec_liodn_base(void) 75db977abfSKumar Gala { 76db977abfSKumar Gala ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR; 77db977abfSKumar Gala u32 base; 78db977abfSKumar Gala 79db977abfSKumar Gala if (!IS_E_PROCESSOR(get_svr())) 80db977abfSKumar Gala return; 81db977abfSKumar Gala 82db977abfSKumar Gala /* QILCR[QSLOM] */ 83db977abfSKumar Gala out_be32(&sec->qilcr_ms, 0x3ff<<16); 84db977abfSKumar Gala 85db977abfSKumar Gala base = (liodn_bases[FSL_HW_PORTAL_SEC].id[0] << 16) | 86db977abfSKumar Gala liodn_bases[FSL_HW_PORTAL_SEC].id[1]; 87db977abfSKumar Gala 88db977abfSKumar Gala out_be32(&sec->qilcr_ls, base); 89db977abfSKumar Gala } 90db977abfSKumar Gala 91db977abfSKumar Gala #ifdef CONFIG_SYS_DPAA_FMAN 92db977abfSKumar Gala static void setup_fman_liodn_base(enum fsl_dpaa_dev dev, 93db977abfSKumar Gala struct liodn_id_table *tbl, int size) 94db977abfSKumar Gala { 95db977abfSKumar Gala int i; 96db977abfSKumar Gala ccsr_fman_t *fm; 97db977abfSKumar Gala u32 base; 98db977abfSKumar Gala 99db977abfSKumar Gala switch(dev) { 100db977abfSKumar Gala case FSL_HW_PORTAL_FMAN1: 101db977abfSKumar Gala fm = (void *)CONFIG_SYS_FSL_FM1_ADDR; 102db977abfSKumar Gala break; 103db977abfSKumar Gala 104db977abfSKumar Gala #if (CONFIG_SYS_NUM_FMAN == 2) 105db977abfSKumar Gala case FSL_HW_PORTAL_FMAN2: 106db977abfSKumar Gala fm = (void *)CONFIG_SYS_FSL_FM2_ADDR; 107db977abfSKumar Gala break; 108db977abfSKumar Gala #endif 109db977abfSKumar Gala default: 110db977abfSKumar Gala printf("Error: Invalid device type to %s\n", __FUNCTION__); 111db977abfSKumar Gala return ; 112db977abfSKumar Gala } 113db977abfSKumar Gala 114db977abfSKumar Gala base = (liodn_bases[dev].id[0] << 16) | liodn_bases[dev].id[0]; 115db977abfSKumar Gala 116db977abfSKumar Gala /* setup all bases the same */ 117db977abfSKumar Gala for (i = 0; i < 32; i++) { 118db977abfSKumar Gala out_be32(&fm->fm_dma.fmdmplr[i], base); 119db977abfSKumar Gala } 120db977abfSKumar Gala 121db977abfSKumar Gala /* update tbl to ... */ 122db977abfSKumar Gala for (i = 0; i < size; i++) 123db977abfSKumar Gala tbl[i].id[0] += liodn_bases[dev].id[0]; 124db977abfSKumar Gala } 125db977abfSKumar Gala #endif 126db977abfSKumar Gala 127db977abfSKumar Gala static void setup_pme_liodn_base(void) 128db977abfSKumar Gala { 129db977abfSKumar Gala #ifdef CONFIG_SYS_DPAA_PME 130db977abfSKumar Gala ccsr_pme_t *pme = (void *)CONFIG_SYS_FSL_CORENET_PME_ADDR; 131db977abfSKumar Gala u32 base = (liodn_bases[FSL_HW_PORTAL_PME].id[0] << 16) | 132db977abfSKumar Gala liodn_bases[FSL_HW_PORTAL_PME].id[1]; 133db977abfSKumar Gala 134db977abfSKumar Gala out_be32(&pme->liodnbr, base); 135db977abfSKumar Gala #endif 136db977abfSKumar Gala } 137db977abfSKumar Gala 1386b3a8d00SKumar Gala #ifdef CONFIG_SYS_FSL_RAID_ENGINE 1396b3a8d00SKumar Gala static void setup_raide_liodn_base(void) 1406b3a8d00SKumar Gala { 1416b3a8d00SKumar Gala struct ccsr_raide *raide = (void *)CONFIG_SYS_FSL_RAID_ENGINE_ADDR; 1426b3a8d00SKumar Gala 1436b3a8d00SKumar Gala /* setup raid engine liodn base for data/desc ; both set to 47 */ 1446b3a8d00SKumar Gala u32 base = (liodn_bases[FSL_HW_PORTAL_RAID_ENGINE].id[0] << 16) | 1456b3a8d00SKumar Gala liodn_bases[FSL_HW_PORTAL_RAID_ENGINE].id[0]; 1466b3a8d00SKumar Gala 1476b3a8d00SKumar Gala out_be32(&raide->liodnbr, base); 1486b3a8d00SKumar Gala } 1496b3a8d00SKumar Gala #endif 1506b3a8d00SKumar Gala 151db977abfSKumar Gala void set_liodns(void) 152db977abfSKumar Gala { 153db977abfSKumar Gala /* setup general liodn offsets */ 154db977abfSKumar Gala set_liodn(liodn_tbl, liodn_tbl_sz); 155db977abfSKumar Gala 1561a0c6421SKumar Gala /* setup SRIO port liodns */ 1571a0c6421SKumar Gala set_srio_liodn(srio_liodn_tbl, srio_liodn_tbl_sz); 1581a0c6421SKumar Gala 159db977abfSKumar Gala /* setup SEC block liodn bases & offsets if we have one */ 160db977abfSKumar Gala if (IS_E_PROCESSOR(get_svr())) { 161db977abfSKumar Gala set_liodn(sec_liodn_tbl, sec_liodn_tbl_sz); 162db977abfSKumar Gala setup_sec_liodn_base(); 163db977abfSKumar Gala } 164db977abfSKumar Gala 165db977abfSKumar Gala /* setup FMAN block(s) liodn bases & offsets if we have one */ 166db977abfSKumar Gala #ifdef CONFIG_SYS_DPAA_FMAN 167db977abfSKumar Gala set_liodn(fman1_liodn_tbl, fman1_liodn_tbl_sz); 168db977abfSKumar Gala setup_fman_liodn_base(FSL_HW_PORTAL_FMAN1, fman1_liodn_tbl, 169db977abfSKumar Gala fman1_liodn_tbl_sz); 170db977abfSKumar Gala 171db977abfSKumar Gala #if (CONFIG_SYS_NUM_FMAN == 2) 172db977abfSKumar Gala set_liodn(fman2_liodn_tbl, fman2_liodn_tbl_sz); 173db977abfSKumar Gala setup_fman_liodn_base(FSL_HW_PORTAL_FMAN2, fman2_liodn_tbl, 174db977abfSKumar Gala fman2_liodn_tbl_sz); 175db977abfSKumar Gala #endif 176db977abfSKumar Gala #endif 177db977abfSKumar Gala /* setup PME liodn base */ 178db977abfSKumar Gala setup_pme_liodn_base(); 1796b3a8d00SKumar Gala 1806b3a8d00SKumar Gala #ifdef CONFIG_SYS_FSL_RAID_ENGINE 1816b3a8d00SKumar Gala /* raid engine ccr addr code for liodn */ 1826b3a8d00SKumar Gala set_liodn(raide_liodn_tbl, raide_liodn_tbl_sz); 1836b3a8d00SKumar Gala setup_raide_liodn_base(); 1846b3a8d00SKumar Gala #endif 185db977abfSKumar Gala } 186db977abfSKumar Gala 187*9c42ef61SKumar Gala static void fdt_fixup_srio_liodn(void *blob, struct srio_liodn_id_table *tbl) 188*9c42ef61SKumar Gala { 189*9c42ef61SKumar Gala int i, srio_off; 190*9c42ef61SKumar Gala 191*9c42ef61SKumar Gala /* search for srio node, if doesn't exist just return - nothing todo */ 192*9c42ef61SKumar Gala srio_off = fdt_node_offset_by_compatible(blob, -1, "fsl,srio"); 193*9c42ef61SKumar Gala if (srio_off < 0) 194*9c42ef61SKumar Gala return ; 195*9c42ef61SKumar Gala 196*9c42ef61SKumar Gala for (i = 0; i < srio_liodn_tbl_sz; i++) { 197*9c42ef61SKumar Gala int off, portid = tbl[i].portid; 198*9c42ef61SKumar Gala 199*9c42ef61SKumar Gala off = fdt_node_offset_by_prop_value(blob, srio_off, 200*9c42ef61SKumar Gala "cell-index", &portid, 4); 201*9c42ef61SKumar Gala if (off >= 0) { 202*9c42ef61SKumar Gala off = fdt_setprop(blob, off, "fsl,liodn", 203*9c42ef61SKumar Gala &tbl[i].id[0], 204*9c42ef61SKumar Gala sizeof(u32) * tbl[i].num_ids); 205*9c42ef61SKumar Gala if (off > 0) 206*9c42ef61SKumar Gala printf("WARNING unable to set fsl,liodn for " 207*9c42ef61SKumar Gala "fsl,srio port %d: %s\n", 208*9c42ef61SKumar Gala portid, fdt_strerror(off)); 209*9c42ef61SKumar Gala } else { 210*9c42ef61SKumar Gala debug("WARNING: couldn't set fsl,liodn for srio: %s.\n", 211*9c42ef61SKumar Gala fdt_strerror(off)); 212*9c42ef61SKumar Gala } 213*9c42ef61SKumar Gala } 214*9c42ef61SKumar Gala } 215*9c42ef61SKumar Gala 216db977abfSKumar Gala static void fdt_fixup_liodn_tbl(void *blob, struct liodn_id_table *tbl, int sz) 217db977abfSKumar Gala { 218db977abfSKumar Gala int i; 219db977abfSKumar Gala 220db977abfSKumar Gala for (i = 0; i < sz; i++) { 221db977abfSKumar Gala int off; 222db977abfSKumar Gala 223db977abfSKumar Gala if (tbl[i].compat == NULL) 224db977abfSKumar Gala continue; 225db977abfSKumar Gala 226db977abfSKumar Gala off = fdt_node_offset_by_compat_reg(blob, 227db977abfSKumar Gala tbl[i].compat, tbl[i].compat_offset); 228db977abfSKumar Gala if (off >= 0) { 229db977abfSKumar Gala off = fdt_setprop(blob, off, "fsl,liodn", 230db977abfSKumar Gala &tbl[i].id[0], 231db977abfSKumar Gala sizeof(u32) * tbl[i].num_ids); 232db977abfSKumar Gala if (off > 0) 233db977abfSKumar Gala printf("WARNING unable to set fsl,liodn for " 234db977abfSKumar Gala "%s: %s\n", 235db977abfSKumar Gala tbl[i].compat, fdt_strerror(off)); 236db977abfSKumar Gala } else { 237db977abfSKumar Gala debug("WARNING: could not set fsl,liodn for %s: %s.\n", 238db977abfSKumar Gala tbl[i].compat, fdt_strerror(off)); 239db977abfSKumar Gala } 240db977abfSKumar Gala } 241db977abfSKumar Gala } 242db977abfSKumar Gala 243db977abfSKumar Gala void fdt_fixup_liodn(void *blob) 244db977abfSKumar Gala { 245*9c42ef61SKumar Gala fdt_fixup_srio_liodn(blob, srio_liodn_tbl); 246*9c42ef61SKumar Gala 247db977abfSKumar Gala fdt_fixup_liodn_tbl(blob, liodn_tbl, liodn_tbl_sz); 248db977abfSKumar Gala #ifdef CONFIG_SYS_DPAA_FMAN 249db977abfSKumar Gala fdt_fixup_liodn_tbl(blob, fman1_liodn_tbl, fman1_liodn_tbl_sz); 250db977abfSKumar Gala #if (CONFIG_SYS_NUM_FMAN == 2) 251db977abfSKumar Gala fdt_fixup_liodn_tbl(blob, fman2_liodn_tbl, fman2_liodn_tbl_sz); 252db977abfSKumar Gala #endif 253db977abfSKumar Gala #endif 254db977abfSKumar Gala fdt_fixup_liodn_tbl(blob, sec_liodn_tbl, sec_liodn_tbl_sz); 2556b3a8d00SKumar Gala 2566b3a8d00SKumar Gala #ifdef CONFIG_SYS_FSL_RAID_ENGINE 2576b3a8d00SKumar Gala fdt_fixup_liodn_tbl(blob, raide_liodn_tbl, raide_liodn_tbl_sz); 2586b3a8d00SKumar Gala #endif 259db977abfSKumar Gala } 260