uboot/drivers/fpga/lattice.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2010
   3 * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
   4 *
   5 * (C) Copyright 2002
   6 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
   7 *
   8 * ispVM functions adapted from Lattice's ispmVMEmbedded code:
   9 * Copyright 2009 Lattice Semiconductor Corp.
  10 *
  11 * SPDX-License-Identifier:     GPL-2.0+
  12 */
  13
  14#include <common.h>
  15#include <malloc.h>
  16#include <fpga.h>
  17#include <lattice.h>
  18
  19static lattice_board_specific_func *pfns;
  20static const char *fpga_image;
  21static unsigned long read_bytes;
  22static unsigned long bufsize;
  23static unsigned short expectedCRC;
  24
  25/*
  26 * External variables and functions declared in ivm_core.c module.
  27 */
  28extern unsigned short g_usCalculatedCRC;
  29extern unsigned short g_usDataType;
  30extern unsigned char *g_pucIntelBuffer;
  31extern unsigned char *g_pucHeapMemory;
  32extern unsigned short g_iHeapCounter;
  33extern unsigned short g_iHEAPSize;
  34extern unsigned short g_usIntelDataIndex;
  35extern unsigned short g_usIntelBufferSize;
  36extern char *const g_szSupportedVersions[];
  37
  38
  39/*
  40 * ispVMDelay
  41 *
  42 * Users must implement a delay to observe a_usTimeDelay, where
  43 * bit 15 of the a_usTimeDelay defines the unit.
  44 *      1 = milliseconds
  45 *      0 = microseconds
  46 * Example:
  47 *      a_usTimeDelay = 0x0001 = 1 microsecond delay.
  48 *      a_usTimeDelay = 0x8001 = 1 millisecond delay.
  49 *
  50 * This subroutine is called upon to provide a delay from 1 millisecond to a few
  51 * hundreds milliseconds each time.
  52 * It is understood that due to a_usTimeDelay is defined as unsigned short, a 16
  53 * bits integer, this function is restricted to produce a delay to 64000
  54 * micro-seconds or 32000 milli-second maximum. The VME file will never pass on
  55 * to this function a delay time > those maximum number. If it needs more than
  56 * those maximum, the VME file will launch the delay function several times to
  57 * realize a larger delay time cummulatively.
  58 * It is perfectly alright to provide a longer delay than required. It is not
  59 * acceptable if the delay is shorter.
  60 */
  61void ispVMDelay(unsigned short delay)
  62{
  63        if (delay & 0x8000)
  64                delay = (delay & ~0x8000) * 1000;
  65        udelay(delay);
  66}
  67
  68void writePort(unsigned char a_ucPins, unsigned char a_ucValue)
  69{
  70        a_ucValue = a_ucValue ? 1 : 0;
  71
  72        switch (a_ucPins) {
  73        case g_ucPinTDI:
  74                pfns->jtag_set_tdi(a_ucValue);
  75                break;
  76        case g_ucPinTCK:
  77                pfns->jtag_set_tck(a_ucValue);
  78                break;
  79        case g_ucPinTMS:
  80                pfns->jtag_set_tms(a_ucValue);
  81                break;
  82        default:
  83                printf("%s: requested unknown pin\n", __func__);
  84        }
  85}
  86
  87unsigned char readPort(void)
  88{
  89        return pfns->jtag_get_tdo();
  90}
  91
  92void sclock(void)
  93{
  94        writePort(g_ucPinTCK, 0x01);
  95        writePort(g_ucPinTCK, 0x00);
  96}
  97
  98void calibration(void)
  99{
 100        /* Apply 2 pulses to TCK. */
 101        writePort(g_ucPinTCK, 0x00);
 102        writePort(g_ucPinTCK, 0x01);
 103        writePort(g_ucPinTCK, 0x00);
 104        writePort(g_ucPinTCK, 0x01);
 105        writePort(g_ucPinTCK, 0x00);
 106
 107        ispVMDelay(0x8001);
 108
 109        /* Apply 2 pulses to TCK. */
 110        writePort(g_ucPinTCK, 0x01);
 111        writePort(g_ucPinTCK, 0x00);
 112        writePort(g_ucPinTCK, 0x01);
 113        writePort(g_ucPinTCK, 0x00);
 114}
 115
 116/*
 117 * GetByte
 118 *
 119 * Returns a byte to the caller. The returned byte depends on the
 120 * g_usDataType register. If the HEAP_IN bit is set, then the byte
 121 * is returned from the HEAP. If the LHEAP_IN bit is set, then
 122 * the byte is returned from the intelligent buffer. Otherwise,
 123 * the byte is returned directly from the VME file.
 124 */
 125unsigned char GetByte(void)
 126{
 127        unsigned char ucData;
 128        unsigned int block_size = 4 * 1024;
 129
 130        if (g_usDataType & HEAP_IN) {
 131
 132                /*
 133                 * Get data from repeat buffer.
 134                 */
 135
 136                if (g_iHeapCounter > g_iHEAPSize) {
 137
 138                        /*
 139                         * Data over-run.
 140                         */
 141
 142                        return 0xFF;
 143                }
 144
 145                ucData = g_pucHeapMemory[g_iHeapCounter++];
 146        } else if (g_usDataType & LHEAP_IN) {
 147
 148                /*
 149                 * Get data from intel buffer.
 150                 */
 151
 152                if (g_usIntelDataIndex >= g_usIntelBufferSize) {
 153                        return 0xFF;
 154                }
 155
 156                ucData = g_pucIntelBuffer[g_usIntelDataIndex++];
 157        } else {
 158                if (read_bytes == bufsize) {
 159                        return 0xFF;
 160                }
 161                ucData = *fpga_image++;
 162                read_bytes++;
 163
 164                if (!(read_bytes % block_size)) {
 165                        printf("Downloading FPGA %ld/%ld completed\r",
 166                                read_bytes,
 167                                bufsize);
 168                }
 169
 170                if (expectedCRC != 0) {
 171                        ispVMCalculateCRC32(ucData);
 172                }
 173        }
 174
 175        return ucData;
 176}
 177
 178signed char ispVM(void)
 179{
 180        char szFileVersion[9]      = { 0 };
 181        signed char cRetCode         = 0;
 182        signed char cIndex           = 0;
 183        signed char cVersionIndex    = 0;
 184        unsigned char ucReadByte     = 0;
 185        unsigned short crc;
 186
 187        g_pucHeapMemory         = NULL;
 188        g_iHeapCounter          = 0;
 189        g_iHEAPSize             = 0;
 190        g_usIntelDataIndex      = 0;
 191        g_usIntelBufferSize     = 0;
 192        g_usCalculatedCRC = 0;
 193        expectedCRC   = 0;
 194        ucReadByte = GetByte();
 195        switch (ucReadByte) {
 196        case FILE_CRC:
 197                crc = (unsigned char)GetByte();
 198                crc <<= 8;
 199                crc |= GetByte();
 200                expectedCRC = crc;
 201
 202                for (cIndex = 0; cIndex < 8; cIndex++)
 203                        szFileVersion[cIndex] = GetByte();
 204
 205                break;
 206        default:
 207                szFileVersion[0] = (signed char) ucReadByte;
 208                for (cIndex = 1; cIndex < 8; cIndex++)
 209                        szFileVersion[cIndex] = GetByte();
 210
 211                break;
 212        }
 213
 214        /*
 215         *
 216         * Compare the VME file version against the supported version.
 217         *
 218         */
 219
 220        for (cVersionIndex = 0; g_szSupportedVersions[cVersionIndex] != 0;
 221                cVersionIndex++) {
 222                for (cIndex = 0; cIndex < 8; cIndex++) {
 223                        if (szFileVersion[cIndex] !=
 224                                g_szSupportedVersions[cVersionIndex][cIndex]) {
 225                                cRetCode = VME_VERSION_FAILURE;
 226                                break;
 227                        }
 228                        cRetCode = 0;
 229                }
 230
 231                if (cRetCode == 0) {
 232                        break;
 233                }
 234        }
 235
 236        if (cRetCode < 0) {
 237                return VME_VERSION_FAILURE;
 238        }
 239
 240        printf("VME file checked: starting downloading to FPGA\n");
 241
 242        ispVMStart();
 243
 244        cRetCode = ispVMCode();
 245
 246        ispVMEnd();
 247        ispVMFreeMem();
 248        puts("\n");
 249
 250        if (cRetCode == 0 && expectedCRC != 0 &&
 251                        (expectedCRC != g_usCalculatedCRC)) {
 252                printf("Expected CRC:   0x%.4X\n", expectedCRC);
 253                printf("Calculated CRC: 0x%.4X\n", g_usCalculatedCRC);
 254                return VME_CRC_FAILURE;
 255        }
 256        return cRetCode;
 257}
 258
 259static int lattice_validate(Lattice_desc *desc, const char *fn)
 260{
 261        int ret_val = false;
 262
 263        if (desc) {
 264                if ((desc->family > min_lattice_type) &&
 265                        (desc->family < max_lattice_type)) {
 266                        if ((desc->iface > min_lattice_iface_type) &&
 267                                (desc->iface < max_lattice_iface_type)) {
 268                                if (desc->size) {
 269                                        ret_val = true;
 270                                } else {
 271                                        printf("%s: NULL part size\n", fn);
 272                                }
 273                        } else {
 274                                printf("%s: Invalid Interface type, %d\n",
 275                                        fn, desc->iface);
 276                        }
 277                } else {
 278                        printf("%s: Invalid family type, %d\n",
 279                                fn, desc->family);
 280                }
 281        } else {
 282                printf("%s: NULL descriptor!\n", fn);
 283        }
 284
 285        return ret_val;
 286}
 287
 288int lattice_load(Lattice_desc *desc, const void *buf, size_t bsize)
 289{
 290        int ret_val = FPGA_FAIL;
 291
 292        if (!lattice_validate(desc, (char *)__func__)) {
 293                printf("%s: Invalid device descriptor\n", __func__);
 294        } else {
 295                pfns = desc->iface_fns;
 296
 297                switch (desc->family) {
 298                case Lattice_XP2:
 299                        fpga_image = buf;
 300                        read_bytes = 0;
 301                        bufsize = bsize;
 302                        debug("%s: Launching the Lattice ISPVME Loader:"
 303                                " addr %p size 0x%lx...\n",
 304                                __func__, fpga_image, bufsize);
 305                        ret_val = ispVM();
 306                        if (ret_val)
 307                                printf("%s: error %d downloading FPGA image\n",
 308                                        __func__, ret_val);
 309                        else
 310                                puts("FPGA downloaded successfully\n");
 311                        break;
 312                default:
 313                        printf("%s: Unsupported family type, %d\n",
 314                                        __func__, desc->family);
 315                }
 316        }
 317
 318        return ret_val;
 319}
 320
 321int lattice_dump(Lattice_desc *desc, const void *buf, size_t bsize)
 322{
 323        puts("Dump not supported for Lattice FPGA\n");
 324
 325        return FPGA_FAIL;
 326
 327}
 328
 329int lattice_info(Lattice_desc *desc)
 330{
 331        int ret_val = FPGA_FAIL;
 332
 333        if (lattice_validate(desc, (char *)__func__)) {
 334                printf("Family:        \t");
 335                switch (desc->family) {
 336                case Lattice_XP2:
 337                        puts("XP2\n");
 338                        break;
 339                        /* Add new family types here */
 340                default:
 341                        printf("Unknown family type, %d\n", desc->family);
 342                }
 343
 344                puts("Interface type:\t");
 345                switch (desc->iface) {
 346                case lattice_jtag_mode:
 347                        puts("JTAG Mode\n");
 348                        break;
 349                        /* Add new interface types here */
 350                default:
 351                        printf("Unsupported interface type, %d\n", desc->iface);
 352                }
 353
 354                printf("Device Size:   \t%d bytes\n",
 355                                desc->size);
 356
 357                if (desc->iface_fns) {
 358                        printf("Device Function Table @ 0x%p\n",
 359                                desc->iface_fns);
 360                        switch (desc->family) {
 361                        case Lattice_XP2:
 362                                break;
 363                                /* Add new family types here */
 364                        default:
 365                                break;
 366                        }
 367                } else {
 368                        puts("No Device Function Table.\n");
 369                }
 370
 371                if (desc->desc)
 372                        printf("Model:         \t%s\n", desc->desc);
 373
 374                ret_val = FPGA_SUCCESS;
 375        } else {
 376                printf("%s: Invalid device descriptor\n", __func__);
 377        }
 378
 379        return ret_val;
 380}
 381