1 /* 2 * Copyright 2008-2011 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <libfdt.h> 9 #include <fdt_support.h> 10 11 #include <asm/processor.h> 12 #include <asm/io.h> 13 14 #include <asm/fsl_portals.h> 15 #include <asm/fsl_liodn.h> 16 17 void setup_portals(void) 18 { 19 ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR; 20 #ifdef CONFIG_FSL_CORENET 21 int i; 22 23 for (i = 0; i < CONFIG_SYS_QMAN_NUM_PORTALS; i++) { 24 u8 sdest = qp_info[i].sdest; 25 u16 fliodn = qp_info[i].fliodn; 26 u16 dliodn = qp_info[i].dliodn; 27 u16 liodn_off = qp_info[i].liodn_offset; 28 29 out_be32(&qman->qcsp[i].qcsp_lio_cfg, (liodn_off << 16) | 30 dliodn); 31 /* set frame liodn */ 32 out_be32(&qman->qcsp[i].qcsp_io_cfg, (sdest << 16) | fliodn); 33 } 34 #endif 35 36 /* Set the Qman initiator BAR to match the LAW (for DQRR stashing) */ 37 #ifdef CONFIG_PHYS_64BIT 38 out_be32(&qman->qcsp_bare, (u32)(CONFIG_SYS_QMAN_MEM_PHYS >> 32)); 39 #endif 40 out_be32(&qman->qcsp_bar, (u32)CONFIG_SYS_QMAN_MEM_PHYS); 41 } 42 43 /* Update portal containter to match LAW setup of portal in phy map */ 44 void fdt_portal(void *blob, const char *compat, const char *container, 45 u64 addr, u32 size) 46 { 47 int off; 48 49 off = fdt_node_offset_by_compatible(blob, -1, compat); 50 if (off < 0) 51 return ; 52 53 off = fdt_parent_offset(blob, off); 54 /* if non-zero assume we have a container */ 55 if (off > 0) { 56 char buf[60]; 57 const char *p, *name; 58 u32 *range; 59 int len; 60 61 /* fixup ranges */ 62 range = fdt_getprop_w(blob, off, "ranges", &len); 63 if (range == NULL) { 64 printf("ERROR: container for %s has no ranges", compat); 65 return ; 66 } 67 68 range[0] = 0; 69 if (len == 16) { 70 range[1] = addr >> 32; 71 range[2] = addr & 0xffffffff; 72 range[3] = size; 73 } else { 74 range[1] = addr & 0xffffffff; 75 range[2] = size; 76 } 77 fdt_setprop_inplace(blob, off, "ranges", range, len); 78 79 /* fixup the name */ 80 name = fdt_get_name(blob, off, &len); 81 p = memchr(name, '@', len); 82 83 if (p) 84 len = p - name; 85 86 /* if we are given a container name check it 87 * against what we found, if it doesnt match exit out */ 88 if (container && (memcmp(container, name, len))) { 89 printf("WARNING: container names didn't match %s %s\n", 90 container, name); 91 return ; 92 } 93 94 memcpy(&buf, name, len); 95 len += sprintf(&buf[len], "@%llx", addr); 96 fdt_set_name(blob, off, buf); 97 return ; 98 } 99 100 printf("ERROR: %s isn't in a container. Not supported\n", compat); 101 } 102 103 static int fdt_qportal(void *blob, int off, int id, char *name, 104 enum fsl_dpaa_dev dev, int create) 105 { 106 int childoff, dev_off, ret = 0; 107 uint32_t dev_handle; 108 #ifdef CONFIG_FSL_CORENET 109 int num; 110 u32 liodns[2]; 111 #endif 112 113 childoff = fdt_subnode_offset(blob, off, name); 114 if (create) { 115 char handle[64], *p; 116 117 strncpy(handle, name, sizeof(handle)); 118 p = strchr(handle, '@'); 119 if (!strncmp(name, "fman", 4)) { 120 *p = *(p + 1); 121 p++; 122 } 123 *p = '\0'; 124 125 dev_off = fdt_path_offset(blob, handle); 126 /* skip this node if alias is not found */ 127 if (dev_off == -FDT_ERR_BADPATH) 128 return 0; 129 if (dev_off < 0) 130 return dev_off; 131 132 if (childoff <= 0) 133 childoff = fdt_add_subnode(blob, off, name); 134 135 /* need to update the dev_off after adding a subnode */ 136 dev_off = fdt_path_offset(blob, handle); 137 if (dev_off < 0) 138 return dev_off; 139 140 if (childoff > 0) { 141 dev_handle = fdt_get_phandle(blob, dev_off); 142 if (dev_handle <= 0) { 143 dev_handle = fdt_alloc_phandle(blob); 144 ret = fdt_set_phandle(blob, dev_off, 145 dev_handle); 146 if (ret < 0) 147 return ret; 148 } 149 150 ret = fdt_setprop(blob, childoff, "dev-handle", 151 &dev_handle, sizeof(dev_handle)); 152 if (ret < 0) 153 return ret; 154 155 #ifdef CONFIG_FSL_CORENET 156 num = get_dpaa_liodn(dev, &liodns[0], id); 157 ret = fdt_setprop(blob, childoff, "fsl,liodn", 158 &liodns[0], sizeof(u32) * num); 159 if (!strncmp(name, "pme", 3)) { 160 u32 pme_rev1, pme_rev2; 161 ccsr_pme_t *pme_regs = 162 (void *)CONFIG_SYS_FSL_CORENET_PME_ADDR; 163 164 pme_rev1 = in_be32(&pme_regs->pm_ip_rev_1); 165 pme_rev2 = in_be32(&pme_regs->pm_ip_rev_2); 166 ret = fdt_setprop(blob, childoff, 167 "fsl,pme-rev1", &pme_rev1, sizeof(u32)); 168 if (ret < 0) 169 return ret; 170 ret = fdt_setprop(blob, childoff, 171 "fsl,pme-rev2", &pme_rev2, sizeof(u32)); 172 } 173 #endif 174 } else { 175 return childoff; 176 } 177 } else { 178 if (childoff > 0) 179 ret = fdt_del_node(blob, childoff); 180 } 181 182 return ret; 183 } 184 185 void fdt_fixup_qportals(void *blob) 186 { 187 int off, err; 188 unsigned int maj, min; 189 unsigned int ip_cfg; 190 ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR; 191 u32 rev_1 = in_be32(&qman->ip_rev_1); 192 u32 rev_2 = in_be32(&qman->ip_rev_2); 193 char compat[64]; 194 int compat_len; 195 196 maj = (rev_1 >> 8) & 0xff; 197 min = rev_1 & 0xff; 198 ip_cfg = rev_2 & 0xff; 199 200 compat_len = sprintf(compat, "fsl,qman-portal-%u.%u.%u", 201 maj, min, ip_cfg) + 1; 202 compat_len += sprintf(compat + compat_len, "fsl,qman-portal") + 1; 203 204 off = fdt_node_offset_by_compatible(blob, -1, "fsl,qman-portal"); 205 while (off != -FDT_ERR_NOTFOUND) { 206 #ifdef CONFIG_FSL_CORENET 207 u32 liodns[2]; 208 #endif 209 const int *ci = fdt_getprop(blob, off, "cell-index", NULL); 210 int i = *ci; 211 #ifdef CONFIG_SYS_DPAA_FMAN 212 int j; 213 #endif 214 215 err = fdt_setprop(blob, off, "compatible", compat, compat_len); 216 if (err < 0) 217 goto err; 218 219 #ifdef CONFIG_FSL_CORENET 220 liodns[0] = qp_info[i].dliodn; 221 liodns[1] = qp_info[i].fliodn; 222 223 err = fdt_setprop(blob, off, "fsl,liodn", 224 &liodns, sizeof(u32) * 2); 225 if (err < 0) 226 goto err; 227 #endif 228 229 i++; 230 231 err = fdt_qportal(blob, off, i, "crypto@0", FSL_HW_PORTAL_SEC, 232 IS_E_PROCESSOR(get_svr())); 233 if (err < 0) 234 goto err; 235 236 #ifdef CONFIG_FSL_CORENET 237 #ifdef CONFIG_SYS_DPAA_PME 238 err = fdt_qportal(blob, off, i, "pme@0", FSL_HW_PORTAL_PME, 1); 239 if (err < 0) 240 goto err; 241 #else 242 fdt_qportal(blob, off, i, "pme@0", FSL_HW_PORTAL_PME, 0); 243 #endif 244 #endif 245 246 #ifdef CONFIG_SYS_DPAA_FMAN 247 for (j = 0; j < CONFIG_SYS_NUM_FMAN; j++) { 248 char name[] = "fman@0"; 249 250 name[sizeof(name) - 2] = '0' + j; 251 err = fdt_qportal(blob, off, i, name, 252 FSL_HW_PORTAL_FMAN1 + j, 1); 253 if (err < 0) 254 goto err; 255 } 256 #endif 257 #ifdef CONFIG_SYS_DPAA_RMAN 258 err = fdt_qportal(blob, off, i, "rman@0", 259 FSL_HW_PORTAL_RMAN, 1); 260 if (err < 0) 261 goto err; 262 #endif 263 264 err: 265 if (err < 0) { 266 printf("ERROR: unable to create props for %s: %s\n", 267 fdt_get_name(blob, off, NULL), fdt_strerror(err)); 268 return; 269 } 270 271 off = fdt_node_offset_by_compatible(blob, off, "fsl,qman-portal"); 272 } 273 } 274 275 void fdt_fixup_bportals(void *blob) 276 { 277 int off, err; 278 unsigned int maj, min; 279 unsigned int ip_cfg; 280 ccsr_bman_t *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR; 281 u32 rev_1 = in_be32(&bman->ip_rev_1); 282 u32 rev_2 = in_be32(&bman->ip_rev_2); 283 char compat[64]; 284 int compat_len; 285 286 maj = (rev_1 >> 8) & 0xff; 287 min = rev_1 & 0xff; 288 289 ip_cfg = rev_2 & 0xff; 290 291 compat_len = sprintf(compat, "fsl,bman-portal-%u.%u.%u", 292 maj, min, ip_cfg) + 1; 293 compat_len += sprintf(compat + compat_len, "fsl,bman-portal") + 1; 294 295 off = fdt_node_offset_by_compatible(blob, -1, "fsl,bman-portal"); 296 while (off != -FDT_ERR_NOTFOUND) { 297 err = fdt_setprop(blob, off, "compatible", compat, compat_len); 298 if (err < 0) { 299 printf("ERROR: unable to create props for %s: %s\n", 300 fdt_get_name(blob, off, NULL), 301 fdt_strerror(err)); 302 return; 303 } 304 305 off = fdt_node_offset_by_compatible(blob, off, "fsl,bman-portal"); 306 } 307 308 } 309