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