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