Commit 03effad96d429331a075573083872675b4b60862

Authored by Chaitanya Sakinam
Committed by Priyanka Jain
1 parent 242e690962

armv8: ls1012a: Pass PPFE firmware to Linux through FDT.

Read Linux PPFE firmware from flash partition and pass it to Linux through
FDT entry. So that we can avoid placing PPFE firmware in Linux rootfs.

Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
Signed-off-by: Anji J <anji.jagarlmudi@nxp.com>

Showing 2 changed files with 205 additions and 1 deletions Side-by-side Diff

arch/arm/cpu/armv8/fsl-layerscape/fdt.c
... ... @@ -428,6 +428,151 @@
428 428 }
429 429 #endif
430 430  
  431 +#ifdef CONFIG_FSL_PFE
  432 +void pfe_set_firmware_in_fdt(void *blob, int pfenode, void *pfw, char *pename,
  433 + unsigned int len)
  434 +{
  435 + int rc, fwnode;
  436 + unsigned int phandle;
  437 + char subnode_str[32], prop_str[32], phandle_str[32], s[64];
  438 +
  439 + sprintf(subnode_str, "pfe-%s-firmware", pename);
  440 + sprintf(prop_str, "fsl,pfe-%s-firmware", pename);
  441 + sprintf(phandle_str, "fsl,%s-firmware", pename);
  442 +
  443 + /*Add PE FW to fdt.*/
  444 + /* Increase the size of the fdt to make room for the node. */
  445 + rc = fdt_increase_size(blob, len);
  446 + if (rc < 0) {
  447 + printf("Unable to make room for %s firmware: %s\n", pename,
  448 + fdt_strerror(rc));
  449 + return;
  450 + }
  451 +
  452 + /* Create the firmware node. */
  453 + fwnode = fdt_add_subnode(blob, pfenode, subnode_str);
  454 + if (fwnode < 0) {
  455 + fdt_get_path(blob, pfenode, s, sizeof(s));
  456 + printf("Could not add firmware node to %s: %s\n", s,
  457 + fdt_strerror(fwnode));
  458 + return;
  459 + }
  460 +
  461 + rc = fdt_setprop_string(blob, fwnode, "compatible", prop_str);
  462 + if (rc < 0) {
  463 + fdt_get_path(blob, fwnode, s, sizeof(s));
  464 + printf("Could not add compatible property to node %s: %s\n", s,
  465 + fdt_strerror(rc));
  466 + return;
  467 + }
  468 +
  469 + rc = fdt_setprop_u32(blob, fwnode, "length", len);
  470 + if (rc < 0) {
  471 + fdt_get_path(blob, fwnode, s, sizeof(s));
  472 + printf("Could not add compatible property to node %s: %s\n", s,
  473 + fdt_strerror(rc));
  474 + return;
  475 + }
  476 +
  477 + /*create phandle and set the property*/
  478 + phandle = fdt_create_phandle(blob, fwnode);
  479 + if (!phandle) {
  480 + fdt_get_path(blob, fwnode, s, sizeof(s));
  481 + printf("Could not add phandle property to node %s: %s\n", s,
  482 + fdt_strerror(rc));
  483 + return;
  484 + }
  485 +
  486 + rc = fdt_setprop(blob, fwnode, phandle_str, pfw, len);
  487 + if (rc < 0) {
  488 + fdt_get_path(blob, fwnode, s, sizeof(s));
  489 + printf("Could not add firmware property to node %s: %s\n", s,
  490 + fdt_strerror(rc));
  491 + return;
  492 + }
  493 +}
  494 +
  495 +void fdt_fixup_pfe_firmware(void *blob)
  496 +{
  497 + int pfenode;
  498 + unsigned int len_class = 0, len_tmu = 0, len_util = 0;
  499 + const char *p;
  500 + void *pclassfw, *ptmufw, *putilfw;
  501 +
  502 + /* The first PFE we find, will contain the actual firmware. */
  503 + pfenode = fdt_node_offset_by_compatible(blob, -1, "fsl,pfe");
  504 + if (pfenode < 0)
  505 + /* Exit silently if there are no PFE devices */
  506 + return;
  507 +
  508 + /* If we already have a firmware node, then also exit silently. */
  509 + if (fdt_node_offset_by_compatible(blob, -1,
  510 + "fsl,pfe-class-firmware") > 0)
  511 + return;
  512 +
  513 + /* If the environment variable is not set, then exit silently */
  514 + p = env_get("class_elf_firmware");
  515 + if (!p)
  516 + return;
  517 +
  518 + pclassfw = (void *)simple_strtoul(p, NULL, 16);
  519 + if (!pclassfw)
  520 + return;
  521 +
  522 + p = env_get("class_elf_size");
  523 + if (!p)
  524 + return;
  525 + len_class = simple_strtoul(p, NULL, 16);
  526 +
  527 + /* If the environment variable is not set, then exit silently */
  528 + p = env_get("tmu_elf_firmware");
  529 + if (!p)
  530 + return;
  531 +
  532 + ptmufw = (void *)simple_strtoul(p, NULL, 16);
  533 + if (!ptmufw)
  534 + return;
  535 +
  536 + p = env_get("tmu_elf_size");
  537 + if (!p)
  538 + return;
  539 + len_tmu = simple_strtoul(p, NULL, 16);
  540 +
  541 + if (len_class == 0 || len_tmu == 0) {
  542 + printf("PFE FW corrupted. CLASS FW size %d, TMU FW size %d\n",
  543 + len_class, len_tmu);
  544 + return;
  545 + }
  546 +
  547 + /*Add CLASS FW to fdt.*/
  548 + pfe_set_firmware_in_fdt(blob, pfenode, pclassfw, "class", len_class);
  549 +
  550 + /*Add TMU FW to fdt.*/
  551 + pfe_set_firmware_in_fdt(blob, pfenode, ptmufw, "tmu", len_tmu);
  552 +
  553 + /* Util PE firmware is handled separately as it is not a usual case*/
  554 + p = env_get("util_elf_firmware");
  555 + if (!p)
  556 + return;
  557 +
  558 + putilfw = (void *)simple_strtoul(p, NULL, 16);
  559 + if (!putilfw)
  560 + return;
  561 +
  562 + p = env_get("util_elf_size");
  563 + if (!p)
  564 + return;
  565 + len_util = simple_strtoul(p, NULL, 16);
  566 +
  567 + if (len_util) {
  568 + printf("PFE Util PE firmware is not added to FDT.\n");
  569 + return;
  570 + }
  571 +
  572 + pfe_set_firmware_in_fdt(blob, pfenode, putilfw, "util", len_util);
  573 +}
  574 +#endif
  575 +
431 576 void ft_cpu_setup(void *blob, bd_t *bd)
432 577 {
433 578 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
... ... @@ -479,6 +624,9 @@
479 624  
480 625 #ifdef CONFIG_SYS_DPAA_FMAN
481 626 fdt_fixup_fman_firmware(blob);
  627 +#endif
  628 +#ifdef CONFIG_FSL_PFE
  629 + fdt_fixup_pfe_firmware(blob);
482 630 #endif
483 631 #ifndef CONFIG_ARCH_LS1012A
484 632 fsl_fdt_disable_usb(blob);
drivers/net/pfe_eth/pfe_firmware.c
... ... @@ -182,7 +182,8 @@
182 182 uintptr_t pfe_img_addr = 0;
183 183 #endif
184 184 int ret = 0;
185   - int fw_count;
  185 + int fw_count, max_fw_count;
  186 + const char *p;
186 187  
187 188 ret = pfe_fit_check();
188 189 if (ret)
... ... @@ -209,6 +210,61 @@
209 210 }
210 211 #endif
211 212  
  213 + p = env_get("load_util");
  214 + if (!p) {
  215 + max_fw_count = 2;
  216 + } else {
  217 + max_fw_count = simple_strtoul(p, NULL, 10);
  218 + if (max_fw_count)
  219 + max_fw_count = 3;
  220 + else
  221 + max_fw_count = 2;
  222 + }
  223 +
  224 + for (fw_count = 0; fw_count < max_fw_count; fw_count++) {
  225 + switch (fw_count) {
  226 + case 0:
  227 + pfe_firmware_name = "class_slowpath";
  228 + break;
  229 + case 1:
  230 + pfe_firmware_name = "tmu_slowpath";
  231 + break;
  232 + case 2:
  233 + pfe_firmware_name = "util_slowpath";
  234 + break;
  235 + }
  236 +
  237 + if (pfe_get_fw(&raw_image_addr, &raw_image_size,
  238 + pfe_firmware_name)) {
  239 + printf("%s firmware couldn't be found in FIT image\n",
  240 + pfe_firmware_name);
  241 + break;
  242 + }
  243 + pfe_firmware = malloc(raw_image_size);
  244 + if (!pfe_firmware)
  245 + return -ENOMEM;
  246 + memcpy((void *)pfe_firmware, (void *)raw_image_addr,
  247 + raw_image_size);
  248 +
  249 + switch (fw_count) {
  250 + case 0:
  251 + env_set_addr("class_elf_firmware", pfe_firmware);
  252 + env_set_addr("class_elf_size", (void *)raw_image_size);
  253 + break;
  254 + case 1:
  255 + env_set_addr("tmu_elf_firmware", pfe_firmware);
  256 + env_set_addr("tmu_elf_size", (void *)raw_image_size);
  257 + break;
  258 + case 2:
  259 + env_set_addr("util_elf_firmware", pfe_firmware);
  260 + env_set_addr("util_elf_size", (void *)raw_image_size);
  261 + break;
  262 + }
  263 + }
  264 +
  265 + raw_image_addr = NULL;
  266 + pfe_firmware = NULL;
  267 + raw_image_size = 0;
212 268 for (fw_count = 0; fw_count < 2; fw_count++) {
213 269 if (fw_count == 0)
214 270 pfe_firmware_name = "class";