1 /* 2 * Copyright (C) 2006-2009 Freescale Semiconductor, Inc. 3 * 4 * Dave Liu <daveliu@freescale.com> 5 * based on source code of Shlomi Gridish 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include "common.h" 11 #include <command.h> 12 #include "asm/errno.h" 13 #include "asm/io.h" 14 #include "linux/immap_qe.h" 15 #include "qe.h" 16 #ifdef CONFIG_LS102XA 17 #include <asm/arch/immap_ls102xa.h> 18 #endif 19 20 #define MPC85xx_DEVDISR_QE_DISABLE 0x1 21 22 qe_map_t *qe_immr = NULL; 23 static qe_snum_t snums[QE_NUM_OF_SNUM]; 24 25 DECLARE_GLOBAL_DATA_PTR; 26 27 void qe_issue_cmd(uint cmd, uint sbc, u8 mcn, u32 cmd_data) 28 { 29 u32 cecr; 30 31 if (cmd == QE_RESET) { 32 out_be32(&qe_immr->cp.cecr,(u32) (cmd | QE_CR_FLG)); 33 } else { 34 out_be32(&qe_immr->cp.cecdr, cmd_data); 35 out_be32(&qe_immr->cp.cecr, (sbc | QE_CR_FLG | 36 ((u32) mcn<<QE_CR_PROTOCOL_SHIFT) | cmd)); 37 } 38 /* Wait for the QE_CR_FLG to clear */ 39 do { 40 cecr = in_be32(&qe_immr->cp.cecr); 41 } while (cecr & QE_CR_FLG); 42 43 return; 44 } 45 46 #ifdef CONFIG_QE 47 uint qe_muram_alloc(uint size, uint align) 48 { 49 uint retloc; 50 uint align_mask, off; 51 uint savebase; 52 53 align_mask = align - 1; 54 savebase = gd->arch.mp_alloc_base; 55 56 off = gd->arch.mp_alloc_base & align_mask; 57 if (off != 0) 58 gd->arch.mp_alloc_base += (align - off); 59 60 if ((off = size & align_mask) != 0) 61 size += (align - off); 62 63 if ((gd->arch.mp_alloc_base + size) >= gd->arch.mp_alloc_top) { 64 gd->arch.mp_alloc_base = savebase; 65 printf("%s: ran out of ram.\n", __FUNCTION__); 66 } 67 68 retloc = gd->arch.mp_alloc_base; 69 gd->arch.mp_alloc_base += size; 70 71 memset((void *)&qe_immr->muram[retloc], 0, size); 72 73 __asm__ __volatile__("sync"); 74 75 return retloc; 76 } 77 #endif 78 79 void *qe_muram_addr(uint offset) 80 { 81 return (void *)&qe_immr->muram[offset]; 82 } 83 84 static void qe_sdma_init(void) 85 { 86 volatile sdma_t *p; 87 uint sdma_buffer_base; 88 89 p = (volatile sdma_t *)&qe_immr->sdma; 90 91 /* All of DMA transaction in bus 1 */ 92 out_be32(&p->sdaqr, 0); 93 out_be32(&p->sdaqmr, 0); 94 95 /* Allocate 2KB temporary buffer for sdma */ 96 sdma_buffer_base = qe_muram_alloc(2048, 4096); 97 out_be32(&p->sdwbcr, sdma_buffer_base & QE_SDEBCR_BA_MASK); 98 99 /* Clear sdma status */ 100 out_be32(&p->sdsr, 0x03000000); 101 102 /* Enable global mode on bus 1, and 2KB buffer size */ 103 out_be32(&p->sdmr, QE_SDMR_GLB_1_MSK | (0x3 << QE_SDMR_CEN_SHIFT)); 104 } 105 106 /* This table is a list of the serial numbers of the Threads, taken from the 107 * "SNUM Table" chart in the QE Reference Manual. The order is not important, 108 * we just need to know what the SNUMs are for the threads. 109 */ 110 static u8 thread_snum[] = { 111 /* Evthreads 16-29 are not supported in MPC8309 */ 112 #if !defined(CONFIG_MPC8309) 113 0x04, 0x05, 0x0c, 0x0d, 114 0x14, 0x15, 0x1c, 0x1d, 115 0x24, 0x25, 0x2c, 0x2d, 116 0x34, 0x35, 117 #endif 118 0x88, 0x89, 0x98, 0x99, 119 0xa8, 0xa9, 0xb8, 0xb9, 120 0xc8, 0xc9, 0xd8, 0xd9, 121 0xe8, 0xe9, 0x08, 0x09, 122 0x18, 0x19, 0x28, 0x29, 123 0x38, 0x39, 0x48, 0x49, 124 0x58, 0x59, 0x68, 0x69, 125 0x78, 0x79, 0x80, 0x81 126 }; 127 128 static void qe_snums_init(void) 129 { 130 int i; 131 132 for (i = 0; i < QE_NUM_OF_SNUM; i++) { 133 snums[i].state = QE_SNUM_STATE_FREE; 134 snums[i].num = thread_snum[i]; 135 } 136 } 137 138 int qe_get_snum(void) 139 { 140 int snum = -EBUSY; 141 int i; 142 143 for (i = 0; i < QE_NUM_OF_SNUM; i++) { 144 if (snums[i].state == QE_SNUM_STATE_FREE) { 145 snums[i].state = QE_SNUM_STATE_USED; 146 snum = snums[i].num; 147 break; 148 } 149 } 150 151 return snum; 152 } 153 154 void qe_put_snum(u8 snum) 155 { 156 int i; 157 158 for (i = 0; i < QE_NUM_OF_SNUM; i++) { 159 if (snums[i].num == snum) { 160 snums[i].state = QE_SNUM_STATE_FREE; 161 break; 162 } 163 } 164 } 165 166 void qe_init(uint qe_base) 167 { 168 /* Init the QE IMMR base */ 169 qe_immr = (qe_map_t *)qe_base; 170 171 #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NOR 172 /* 173 * Upload microcode to IRAM for those SOCs which do not have ROM in QE. 174 */ 175 qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR); 176 177 /* enable the microcode in IRAM */ 178 out_be32(&qe_immr->iram.iready,QE_IRAM_READY); 179 #endif 180 181 gd->arch.mp_alloc_base = QE_DATAONLY_BASE; 182 gd->arch.mp_alloc_top = gd->arch.mp_alloc_base + QE_DATAONLY_SIZE; 183 184 qe_sdma_init(); 185 qe_snums_init(); 186 } 187 188 #ifdef CONFIG_U_QE 189 void u_qe_init(void) 190 { 191 uint qe_base = CONFIG_SYS_IMMR + 0x01400000; /* QE immr base */ 192 qe_immr = (qe_map_t *)qe_base; 193 194 u_qe_upload_firmware((const void *)CONFIG_SYS_QE_FW_ADDR); 195 out_be32(&qe_immr->iram.iready, QE_IRAM_READY); 196 } 197 #endif 198 199 #ifdef CONFIG_U_QE 200 void u_qe_resume(void) 201 { 202 qe_map_t *qe_immrr; 203 uint qe_base = CONFIG_SYS_IMMR + QE_IMMR_OFFSET; /* QE immr base */ 204 qe_immrr = (qe_map_t *)qe_base; 205 206 u_qe_firmware_resume((const void *)CONFIG_SYS_QE_FW_ADDR, qe_immrr); 207 out_be32(&qe_immrr->iram.iready, QE_IRAM_READY); 208 } 209 #endif 210 211 void qe_reset(void) 212 { 213 qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID, 214 (u8) QE_CR_PROTOCOL_UNSPECIFIED, 0); 215 } 216 217 void qe_assign_page(uint snum, uint para_ram_base) 218 { 219 u32 cecr; 220 221 out_be32(&qe_immr->cp.cecdr, para_ram_base); 222 out_be32(&qe_immr->cp.cecr, ((u32) snum<<QE_CR_ASSIGN_PAGE_SNUM_SHIFT) 223 | QE_CR_FLG | QE_ASSIGN_PAGE); 224 225 /* Wait for the QE_CR_FLG to clear */ 226 do { 227 cecr = in_be32(&qe_immr->cp.cecr); 228 } while (cecr & QE_CR_FLG ); 229 230 return; 231 } 232 233 /* 234 * brg: 0~15 as BRG1~BRG16 235 rate: baud rate 236 * BRG input clock comes from the BRGCLK (internal clock generated from 237 the QE clock, it is one-half of the QE clock), If need the clock source 238 from CLKn pin, we have te change the function. 239 */ 240 241 #define BRG_CLK (gd->arch.brg_clk) 242 243 #ifdef CONFIG_QE 244 int qe_set_brg(uint brg, uint rate) 245 { 246 volatile uint *bp; 247 u32 divisor; 248 int div16 = 0; 249 250 if (brg >= QE_NUM_OF_BRGS) 251 return -EINVAL; 252 bp = (uint *)&qe_immr->brg.brgc1; 253 bp += brg; 254 255 divisor = (BRG_CLK / rate); 256 if (divisor > QE_BRGC_DIVISOR_MAX + 1) { 257 div16 = 1; 258 divisor /= 16; 259 } 260 261 *bp = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE; 262 __asm__ __volatile__("sync"); 263 264 if (div16) { 265 *bp |= QE_BRGC_DIV16; 266 __asm__ __volatile__("sync"); 267 } 268 269 return 0; 270 } 271 #endif 272 273 /* Set ethernet MII clock master 274 */ 275 int qe_set_mii_clk_src(int ucc_num) 276 { 277 u32 cmxgcr; 278 279 /* check if the UCC number is in range. */ 280 if ((ucc_num > UCC_MAX_NUM - 1) || (ucc_num < 0)) { 281 printf("%s: ucc num not in ranges\n", __FUNCTION__); 282 return -EINVAL; 283 } 284 285 cmxgcr = in_be32(&qe_immr->qmx.cmxgcr); 286 cmxgcr &= ~QE_CMXGCR_MII_ENET_MNG_MASK; 287 cmxgcr |= (ucc_num <<QE_CMXGCR_MII_ENET_MNG_SHIFT); 288 out_be32(&qe_immr->qmx.cmxgcr, cmxgcr); 289 290 return 0; 291 } 292 293 /* Firmware information stored here for qe_get_firmware_info() */ 294 static struct qe_firmware_info qe_firmware_info; 295 296 /* 297 * Set to 1 if QE firmware has been uploaded, and therefore 298 * qe_firmware_info contains valid data. 299 */ 300 static int qe_firmware_uploaded; 301 302 /* 303 * Upload a QE microcode 304 * 305 * This function is a worker function for qe_upload_firmware(). It does 306 * the actual uploading of the microcode. 307 */ 308 static void qe_upload_microcode(const void *base, 309 const struct qe_microcode *ucode) 310 { 311 const u32 *code = base + be32_to_cpu(ucode->code_offset); 312 unsigned int i; 313 314 if (ucode->major || ucode->minor || ucode->revision) 315 printf("QE: uploading microcode '%s' version %u.%u.%u\n", 316 (char *)ucode->id, (u16)ucode->major, (u16)ucode->minor, 317 (u16)ucode->revision); 318 else 319 printf("QE: uploading microcode '%s'\n", (char *)ucode->id); 320 321 /* Use auto-increment */ 322 out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) | 323 QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR); 324 325 for (i = 0; i < be32_to_cpu(ucode->count); i++) 326 out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i])); 327 } 328 329 /* 330 * Upload a microcode to the I-RAM at a specific address. 331 * 332 * See docs/README.qe_firmware for information on QE microcode uploading. 333 * 334 * Currently, only version 1 is supported, so the 'version' field must be 335 * set to 1. 336 * 337 * The SOC model and revision are not validated, they are only displayed for 338 * informational purposes. 339 * 340 * 'calc_size' is the calculated size, in bytes, of the firmware structure and 341 * all of the microcode structures, minus the CRC. 342 * 343 * 'length' is the size that the structure says it is, including the CRC. 344 */ 345 int qe_upload_firmware(const struct qe_firmware *firmware) 346 { 347 unsigned int i; 348 unsigned int j; 349 u32 crc; 350 size_t calc_size = sizeof(struct qe_firmware); 351 size_t length; 352 const struct qe_header *hdr; 353 #ifdef CONFIG_DEEP_SLEEP 354 #ifdef CONFIG_LS102XA 355 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; 356 #else 357 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 358 #endif 359 #endif 360 if (!firmware) { 361 printf("Invalid address\n"); 362 return -EINVAL; 363 } 364 365 hdr = &firmware->header; 366 length = be32_to_cpu(hdr->length); 367 368 /* Check the magic */ 369 if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || 370 (hdr->magic[2] != 'F')) { 371 printf("QE microcode not found\n"); 372 #ifdef CONFIG_DEEP_SLEEP 373 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE); 374 #endif 375 return -EPERM; 376 } 377 378 /* Check the version */ 379 if (hdr->version != 1) { 380 printf("Unsupported version\n"); 381 return -EPERM; 382 } 383 384 /* Validate some of the fields */ 385 if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) { 386 printf("Invalid data\n"); 387 return -EINVAL; 388 } 389 390 /* Validate the length and check if there's a CRC */ 391 calc_size += (firmware->count - 1) * sizeof(struct qe_microcode); 392 393 for (i = 0; i < firmware->count; i++) 394 /* 395 * For situations where the second RISC uses the same microcode 396 * as the first, the 'code_offset' and 'count' fields will be 397 * zero, so it's okay to add those. 398 */ 399 calc_size += sizeof(u32) * 400 be32_to_cpu(firmware->microcode[i].count); 401 402 /* Validate the length */ 403 if (length != calc_size + sizeof(u32)) { 404 printf("Invalid length\n"); 405 return -EPERM; 406 } 407 408 /* 409 * Validate the CRC. We would normally call crc32_no_comp(), but that 410 * function isn't available unless you turn on JFFS support. 411 */ 412 crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size)); 413 if (crc != (crc32(-1, (const void *) firmware, calc_size) ^ -1)) { 414 printf("Firmware CRC is invalid\n"); 415 return -EIO; 416 } 417 418 /* 419 * If the microcode calls for it, split the I-RAM. 420 */ 421 if (!firmware->split) { 422 out_be16(&qe_immr->cp.cercr, 423 in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR); 424 } 425 426 if (firmware->soc.model) 427 printf("Firmware '%s' for %u V%u.%u\n", 428 firmware->id, be16_to_cpu(firmware->soc.model), 429 firmware->soc.major, firmware->soc.minor); 430 else 431 printf("Firmware '%s'\n", firmware->id); 432 433 /* 434 * The QE only supports one microcode per RISC, so clear out all the 435 * saved microcode information and put in the new. 436 */ 437 memset(&qe_firmware_info, 0, sizeof(qe_firmware_info)); 438 strncpy(qe_firmware_info.id, (char *)firmware->id, 62); 439 qe_firmware_info.extended_modes = firmware->extended_modes; 440 memcpy(qe_firmware_info.vtraps, firmware->vtraps, 441 sizeof(firmware->vtraps)); 442 qe_firmware_uploaded = 1; 443 444 /* Loop through each microcode. */ 445 for (i = 0; i < firmware->count; i++) { 446 const struct qe_microcode *ucode = &firmware->microcode[i]; 447 448 /* Upload a microcode if it's present */ 449 if (ucode->code_offset) 450 qe_upload_microcode(firmware, ucode); 451 452 /* Program the traps for this processor */ 453 for (j = 0; j < 16; j++) { 454 u32 trap = be32_to_cpu(ucode->traps[j]); 455 456 if (trap) 457 out_be32(&qe_immr->rsp[i].tibcr[j], trap); 458 } 459 460 /* Enable traps */ 461 out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr)); 462 } 463 464 return 0; 465 } 466 467 #ifdef CONFIG_U_QE 468 /* 469 * Upload a microcode to the I-RAM at a specific address. 470 * 471 * See docs/README.qe_firmware for information on QE microcode uploading. 472 * 473 * Currently, only version 1 is supported, so the 'version' field must be 474 * set to 1. 475 * 476 * The SOC model and revision are not validated, they are only displayed for 477 * informational purposes. 478 * 479 * 'calc_size' is the calculated size, in bytes, of the firmware structure and 480 * all of the microcode structures, minus the CRC. 481 * 482 * 'length' is the size that the structure says it is, including the CRC. 483 */ 484 int u_qe_upload_firmware(const struct qe_firmware *firmware) 485 { 486 unsigned int i; 487 unsigned int j; 488 u32 crc; 489 size_t calc_size = sizeof(struct qe_firmware); 490 size_t length; 491 const struct qe_header *hdr; 492 #ifdef CONFIG_DEEP_SLEEP 493 #ifdef CONFIG_LS102XA 494 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; 495 #else 496 ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 497 #endif 498 #endif 499 if (!firmware) { 500 printf("Invalid address\n"); 501 return -EINVAL; 502 } 503 504 hdr = &firmware->header; 505 length = be32_to_cpu(hdr->length); 506 507 /* Check the magic */ 508 if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || 509 (hdr->magic[2] != 'F')) { 510 printf("Not a microcode\n"); 511 #ifdef CONFIG_DEEP_SLEEP 512 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE); 513 #endif 514 return -EPERM; 515 } 516 517 /* Check the version */ 518 if (hdr->version != 1) { 519 printf("Unsupported version\n"); 520 return -EPERM; 521 } 522 523 /* Validate some of the fields */ 524 if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) { 525 printf("Invalid data\n"); 526 return -EINVAL; 527 } 528 529 /* Validate the length and check if there's a CRC */ 530 calc_size += (firmware->count - 1) * sizeof(struct qe_microcode); 531 532 for (i = 0; i < firmware->count; i++) 533 /* 534 * For situations where the second RISC uses the same microcode 535 * as the first, the 'code_offset' and 'count' fields will be 536 * zero, so it's okay to add those. 537 */ 538 calc_size += sizeof(u32) * 539 be32_to_cpu(firmware->microcode[i].count); 540 541 /* Validate the length */ 542 if (length != calc_size + sizeof(u32)) { 543 printf("Invalid length\n"); 544 return -EPERM; 545 } 546 547 /* 548 * Validate the CRC. We would normally call crc32_no_comp(), but that 549 * function isn't available unless you turn on JFFS support. 550 */ 551 crc = be32_to_cpu(*(u32 *)((void *)firmware + calc_size)); 552 if (crc != (crc32(-1, (const void *)firmware, calc_size) ^ -1)) { 553 printf("Firmware CRC is invalid\n"); 554 return -EIO; 555 } 556 557 /* 558 * If the microcode calls for it, split the I-RAM. 559 */ 560 if (!firmware->split) { 561 out_be16(&qe_immr->cp.cercr, 562 in_be16(&qe_immr->cp.cercr) | QE_CP_CERCR_CIR); 563 } 564 565 if (firmware->soc.model) 566 printf("Firmware '%s' for %u V%u.%u\n", 567 firmware->id, be16_to_cpu(firmware->soc.model), 568 firmware->soc.major, firmware->soc.minor); 569 else 570 printf("Firmware '%s'\n", firmware->id); 571 572 /* Loop through each microcode. */ 573 for (i = 0; i < firmware->count; i++) { 574 const struct qe_microcode *ucode = &firmware->microcode[i]; 575 576 /* Upload a microcode if it's present */ 577 if (ucode->code_offset) 578 qe_upload_microcode(firmware, ucode); 579 580 /* Program the traps for this processor */ 581 for (j = 0; j < 16; j++) { 582 u32 trap = be32_to_cpu(ucode->traps[j]); 583 584 if (trap) 585 out_be32(&qe_immr->rsp[i].tibcr[j], trap); 586 } 587 588 /* Enable traps */ 589 out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr)); 590 } 591 592 return 0; 593 } 594 #endif 595 596 #ifdef CONFIG_U_QE 597 int u_qe_firmware_resume(const struct qe_firmware *firmware, qe_map_t *qe_immrr) 598 { 599 unsigned int i; 600 unsigned int j; 601 const struct qe_header *hdr; 602 const u32 *code; 603 #ifdef CONFIG_DEEP_SLEEP 604 #ifdef CONFIG_PPC 605 ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 606 #else 607 struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; 608 #endif 609 #endif 610 611 if (!firmware) 612 return -EINVAL; 613 614 hdr = &firmware->header; 615 616 /* Check the magic */ 617 if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || 618 (hdr->magic[2] != 'F')) { 619 #ifdef CONFIG_DEEP_SLEEP 620 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE); 621 #endif 622 return -EPERM; 623 } 624 625 /* 626 * If the microcode calls for it, split the I-RAM. 627 */ 628 if (!firmware->split) { 629 out_be16(&qe_immrr->cp.cercr, 630 in_be16(&qe_immrr->cp.cercr) | QE_CP_CERCR_CIR); 631 } 632 633 /* Loop through each microcode. */ 634 for (i = 0; i < firmware->count; i++) { 635 const struct qe_microcode *ucode = &firmware->microcode[i]; 636 637 /* Upload a microcode if it's present */ 638 if (!ucode->code_offset) 639 return 0; 640 641 code = (const void *)firmware + be32_to_cpu(ucode->code_offset); 642 643 /* Use auto-increment */ 644 out_be32(&qe_immrr->iram.iadd, be32_to_cpu(ucode->iram_offset) | 645 QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR); 646 647 for (i = 0; i < be32_to_cpu(ucode->count); i++) 648 out_be32(&qe_immrr->iram.idata, be32_to_cpu(code[i])); 649 650 /* Program the traps for this processor */ 651 for (j = 0; j < 16; j++) { 652 u32 trap = be32_to_cpu(ucode->traps[j]); 653 654 if (trap) 655 out_be32(&qe_immrr->rsp[i].tibcr[j], trap); 656 } 657 658 /* Enable traps */ 659 out_be32(&qe_immrr->rsp[i].eccr, be32_to_cpu(ucode->eccr)); 660 } 661 662 return 0; 663 } 664 #endif 665 666 struct qe_firmware_info *qe_get_firmware_info(void) 667 { 668 return qe_firmware_uploaded ? &qe_firmware_info : NULL; 669 } 670 671 static int qe_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 672 { 673 ulong addr; 674 675 if (argc < 3) 676 return cmd_usage(cmdtp); 677 678 if (strcmp(argv[1], "fw") == 0) { 679 addr = simple_strtoul(argv[2], NULL, 16); 680 681 if (!addr) { 682 printf("Invalid address\n"); 683 return -EINVAL; 684 } 685 686 /* 687 * If a length was supplied, compare that with the 'length' 688 * field. 689 */ 690 691 if (argc > 3) { 692 ulong length = simple_strtoul(argv[3], NULL, 16); 693 struct qe_firmware *firmware = (void *) addr; 694 695 if (length != be32_to_cpu(firmware->header.length)) { 696 printf("Length mismatch\n"); 697 return -EINVAL; 698 } 699 } 700 701 return qe_upload_firmware((const struct qe_firmware *) addr); 702 } 703 704 return cmd_usage(cmdtp); 705 } 706 707 U_BOOT_CMD( 708 qe, 4, 0, qe_cmd, 709 "QUICC Engine commands", 710 "fw <addr> [<length>] - Upload firmware binary at address <addr> to " 711 "the QE,\n" 712 "\twith optional length <length> verification." 713 ); 714