13b8ac464SStefano Babic /*
23b8ac464SStefano Babic * (C) Copyright 2010
33b8ac464SStefano Babic * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
43b8ac464SStefano Babic *
53b8ac464SStefano Babic * (C) Copyright 2002
63b8ac464SStefano Babic * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
73b8ac464SStefano Babic *
83b8ac464SStefano Babic * ispVM functions adapted from Lattice's ispmVMEmbedded code:
93b8ac464SStefano Babic * Copyright 2009 Lattice Semiconductor Corp.
103b8ac464SStefano Babic *
11*1a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
123b8ac464SStefano Babic */
133b8ac464SStefano Babic
143b8ac464SStefano Babic #include <common.h>
153b8ac464SStefano Babic #include <malloc.h>
163b8ac464SStefano Babic #include <fpga.h>
173b8ac464SStefano Babic #include <lattice.h>
183b8ac464SStefano Babic
193b8ac464SStefano Babic static lattice_board_specific_func *pfns;
20fb2d6efbSWolfgang Denk static const char *fpga_image;
213b8ac464SStefano Babic static unsigned long read_bytes;
223b8ac464SStefano Babic static unsigned long bufsize;
233b8ac464SStefano Babic static unsigned short expectedCRC;
243b8ac464SStefano Babic
253b8ac464SStefano Babic /*
263b8ac464SStefano Babic * External variables and functions declared in ivm_core.c module.
273b8ac464SStefano Babic */
283b8ac464SStefano Babic extern unsigned short g_usCalculatedCRC;
293b8ac464SStefano Babic extern unsigned short g_usDataType;
303b8ac464SStefano Babic extern unsigned char *g_pucIntelBuffer;
313b8ac464SStefano Babic extern unsigned char *g_pucHeapMemory;
323b8ac464SStefano Babic extern unsigned short g_iHeapCounter;
333b8ac464SStefano Babic extern unsigned short g_iHEAPSize;
343b8ac464SStefano Babic extern unsigned short g_usIntelDataIndex;
353b8ac464SStefano Babic extern unsigned short g_usIntelBufferSize;
363b8ac464SStefano Babic extern char *const g_szSupportedVersions[];
373b8ac464SStefano Babic
383b8ac464SStefano Babic
393b8ac464SStefano Babic /*
403b8ac464SStefano Babic * ispVMDelay
413b8ac464SStefano Babic *
423b8ac464SStefano Babic * Users must implement a delay to observe a_usTimeDelay, where
433b8ac464SStefano Babic * bit 15 of the a_usTimeDelay defines the unit.
443b8ac464SStefano Babic * 1 = milliseconds
453b8ac464SStefano Babic * 0 = microseconds
463b8ac464SStefano Babic * Example:
473b8ac464SStefano Babic * a_usTimeDelay = 0x0001 = 1 microsecond delay.
483b8ac464SStefano Babic * a_usTimeDelay = 0x8001 = 1 millisecond delay.
493b8ac464SStefano Babic *
503b8ac464SStefano Babic * This subroutine is called upon to provide a delay from 1 millisecond to a few
513b8ac464SStefano Babic * hundreds milliseconds each time.
523b8ac464SStefano Babic * It is understood that due to a_usTimeDelay is defined as unsigned short, a 16
533b8ac464SStefano Babic * bits integer, this function is restricted to produce a delay to 64000
543b8ac464SStefano Babic * micro-seconds or 32000 milli-second maximum. The VME file will never pass on
553b8ac464SStefano Babic * to this function a delay time > those maximum number. If it needs more than
563b8ac464SStefano Babic * those maximum, the VME file will launch the delay function several times to
573b8ac464SStefano Babic * realize a larger delay time cummulatively.
583b8ac464SStefano Babic * It is perfectly alright to provide a longer delay than required. It is not
593b8ac464SStefano Babic * acceptable if the delay is shorter.
603b8ac464SStefano Babic */
ispVMDelay(unsigned short delay)613b8ac464SStefano Babic void ispVMDelay(unsigned short delay)
623b8ac464SStefano Babic {
633b8ac464SStefano Babic if (delay & 0x8000)
643b8ac464SStefano Babic delay = (delay & ~0x8000) * 1000;
653b8ac464SStefano Babic udelay(delay);
663b8ac464SStefano Babic }
673b8ac464SStefano Babic
writePort(unsigned char a_ucPins,unsigned char a_ucValue)683b8ac464SStefano Babic void writePort(unsigned char a_ucPins, unsigned char a_ucValue)
693b8ac464SStefano Babic {
703b8ac464SStefano Babic a_ucValue = a_ucValue ? 1 : 0;
713b8ac464SStefano Babic
723b8ac464SStefano Babic switch (a_ucPins) {
733b8ac464SStefano Babic case g_ucPinTDI:
743b8ac464SStefano Babic pfns->jtag_set_tdi(a_ucValue);
753b8ac464SStefano Babic break;
763b8ac464SStefano Babic case g_ucPinTCK:
773b8ac464SStefano Babic pfns->jtag_set_tck(a_ucValue);
783b8ac464SStefano Babic break;
793b8ac464SStefano Babic case g_ucPinTMS:
803b8ac464SStefano Babic pfns->jtag_set_tms(a_ucValue);
813b8ac464SStefano Babic break;
823b8ac464SStefano Babic default:
833b8ac464SStefano Babic printf("%s: requested unknown pin\n", __func__);
843b8ac464SStefano Babic }
853b8ac464SStefano Babic }
863b8ac464SStefano Babic
readPort(void)873b8ac464SStefano Babic unsigned char readPort(void)
883b8ac464SStefano Babic {
893b8ac464SStefano Babic return pfns->jtag_get_tdo();
903b8ac464SStefano Babic }
913b8ac464SStefano Babic
sclock(void)923b8ac464SStefano Babic void sclock(void)
933b8ac464SStefano Babic {
943b8ac464SStefano Babic writePort(g_ucPinTCK, 0x01);
953b8ac464SStefano Babic writePort(g_ucPinTCK, 0x00);
963b8ac464SStefano Babic }
973b8ac464SStefano Babic
calibration(void)983b8ac464SStefano Babic void calibration(void)
993b8ac464SStefano Babic {
1003b8ac464SStefano Babic /* Apply 2 pulses to TCK. */
1013b8ac464SStefano Babic writePort(g_ucPinTCK, 0x00);
1023b8ac464SStefano Babic writePort(g_ucPinTCK, 0x01);
1033b8ac464SStefano Babic writePort(g_ucPinTCK, 0x00);
1043b8ac464SStefano Babic writePort(g_ucPinTCK, 0x01);
1053b8ac464SStefano Babic writePort(g_ucPinTCK, 0x00);
1063b8ac464SStefano Babic
1073b8ac464SStefano Babic ispVMDelay(0x8001);
1083b8ac464SStefano Babic
1093b8ac464SStefano Babic /* Apply 2 pulses to TCK. */
1103b8ac464SStefano Babic writePort(g_ucPinTCK, 0x01);
1113b8ac464SStefano Babic writePort(g_ucPinTCK, 0x00);
1123b8ac464SStefano Babic writePort(g_ucPinTCK, 0x01);
1133b8ac464SStefano Babic writePort(g_ucPinTCK, 0x00);
1143b8ac464SStefano Babic }
1153b8ac464SStefano Babic
1163b8ac464SStefano Babic /*
1173b8ac464SStefano Babic * GetByte
1183b8ac464SStefano Babic *
1193b8ac464SStefano Babic * Returns a byte to the caller. The returned byte depends on the
1203b8ac464SStefano Babic * g_usDataType register. If the HEAP_IN bit is set, then the byte
1213b8ac464SStefano Babic * is returned from the HEAP. If the LHEAP_IN bit is set, then
1223b8ac464SStefano Babic * the byte is returned from the intelligent buffer. Otherwise,
1233b8ac464SStefano Babic * the byte is returned directly from the VME file.
1243b8ac464SStefano Babic */
GetByte(void)1253b8ac464SStefano Babic unsigned char GetByte(void)
1263b8ac464SStefano Babic {
1273b8ac464SStefano Babic unsigned char ucData;
1283b8ac464SStefano Babic unsigned int block_size = 4 * 1024;
1293b8ac464SStefano Babic
1303b8ac464SStefano Babic if (g_usDataType & HEAP_IN) {
1313b8ac464SStefano Babic
1323b8ac464SStefano Babic /*
1333b8ac464SStefano Babic * Get data from repeat buffer.
1343b8ac464SStefano Babic */
1353b8ac464SStefano Babic
1363b8ac464SStefano Babic if (g_iHeapCounter > g_iHEAPSize) {
1373b8ac464SStefano Babic
1383b8ac464SStefano Babic /*
1393b8ac464SStefano Babic * Data over-run.
1403b8ac464SStefano Babic */
1413b8ac464SStefano Babic
1423b8ac464SStefano Babic return 0xFF;
1433b8ac464SStefano Babic }
1443b8ac464SStefano Babic
1453b8ac464SStefano Babic ucData = g_pucHeapMemory[g_iHeapCounter++];
1463b8ac464SStefano Babic } else if (g_usDataType & LHEAP_IN) {
1473b8ac464SStefano Babic
1483b8ac464SStefano Babic /*
1493b8ac464SStefano Babic * Get data from intel buffer.
1503b8ac464SStefano Babic */
1513b8ac464SStefano Babic
1523b8ac464SStefano Babic if (g_usIntelDataIndex >= g_usIntelBufferSize) {
1533b8ac464SStefano Babic return 0xFF;
1543b8ac464SStefano Babic }
1553b8ac464SStefano Babic
1563b8ac464SStefano Babic ucData = g_pucIntelBuffer[g_usIntelDataIndex++];
1573b8ac464SStefano Babic } else {
1583b8ac464SStefano Babic if (read_bytes == bufsize) {
1593b8ac464SStefano Babic return 0xFF;
1603b8ac464SStefano Babic }
1613b8ac464SStefano Babic ucData = *fpga_image++;
1623b8ac464SStefano Babic read_bytes++;
1633b8ac464SStefano Babic
1643b8ac464SStefano Babic if (!(read_bytes % block_size)) {
1653b8ac464SStefano Babic printf("Downloading FPGA %ld/%ld completed\r",
1663b8ac464SStefano Babic read_bytes,
1673b8ac464SStefano Babic bufsize);
1683b8ac464SStefano Babic }
1693b8ac464SStefano Babic
1703b8ac464SStefano Babic if (expectedCRC != 0) {
1713b8ac464SStefano Babic ispVMCalculateCRC32(ucData);
1723b8ac464SStefano Babic }
1733b8ac464SStefano Babic }
1743b8ac464SStefano Babic
1753b8ac464SStefano Babic return ucData;
1763b8ac464SStefano Babic }
1773b8ac464SStefano Babic
ispVM(void)1783b8ac464SStefano Babic signed char ispVM(void)
1793b8ac464SStefano Babic {
1803b8ac464SStefano Babic char szFileVersion[9] = { 0 };
1813b8ac464SStefano Babic signed char cRetCode = 0;
1823b8ac464SStefano Babic signed char cIndex = 0;
1833b8ac464SStefano Babic signed char cVersionIndex = 0;
1843b8ac464SStefano Babic unsigned char ucReadByte = 0;
1853b8ac464SStefano Babic unsigned short crc;
1863b8ac464SStefano Babic
1873b8ac464SStefano Babic g_pucHeapMemory = NULL;
1883b8ac464SStefano Babic g_iHeapCounter = 0;
1893b8ac464SStefano Babic g_iHEAPSize = 0;
1903b8ac464SStefano Babic g_usIntelDataIndex = 0;
1913b8ac464SStefano Babic g_usIntelBufferSize = 0;
1923b8ac464SStefano Babic g_usCalculatedCRC = 0;
1933b8ac464SStefano Babic expectedCRC = 0;
1943b8ac464SStefano Babic ucReadByte = GetByte();
1953b8ac464SStefano Babic switch (ucReadByte) {
1963b8ac464SStefano Babic case FILE_CRC:
1973b8ac464SStefano Babic crc = (unsigned char)GetByte();
1983b8ac464SStefano Babic crc <<= 8;
1993b8ac464SStefano Babic crc |= GetByte();
2003b8ac464SStefano Babic expectedCRC = crc;
2013b8ac464SStefano Babic
2023b8ac464SStefano Babic for (cIndex = 0; cIndex < 8; cIndex++)
2033b8ac464SStefano Babic szFileVersion[cIndex] = GetByte();
2043b8ac464SStefano Babic
2053b8ac464SStefano Babic break;
2063b8ac464SStefano Babic default:
2073b8ac464SStefano Babic szFileVersion[0] = (signed char) ucReadByte;
2083b8ac464SStefano Babic for (cIndex = 1; cIndex < 8; cIndex++)
2093b8ac464SStefano Babic szFileVersion[cIndex] = GetByte();
2103b8ac464SStefano Babic
2113b8ac464SStefano Babic break;
2123b8ac464SStefano Babic }
2133b8ac464SStefano Babic
2143b8ac464SStefano Babic /*
2153b8ac464SStefano Babic *
2163b8ac464SStefano Babic * Compare the VME file version against the supported version.
2173b8ac464SStefano Babic *
2183b8ac464SStefano Babic */
2193b8ac464SStefano Babic
2203b8ac464SStefano Babic for (cVersionIndex = 0; g_szSupportedVersions[cVersionIndex] != 0;
2213b8ac464SStefano Babic cVersionIndex++) {
2223b8ac464SStefano Babic for (cIndex = 0; cIndex < 8; cIndex++) {
2233b8ac464SStefano Babic if (szFileVersion[cIndex] !=
2243b8ac464SStefano Babic g_szSupportedVersions[cVersionIndex][cIndex]) {
2253b8ac464SStefano Babic cRetCode = VME_VERSION_FAILURE;
2263b8ac464SStefano Babic break;
2273b8ac464SStefano Babic }
2283b8ac464SStefano Babic cRetCode = 0;
2293b8ac464SStefano Babic }
2303b8ac464SStefano Babic
2313b8ac464SStefano Babic if (cRetCode == 0) {
2323b8ac464SStefano Babic break;
2333b8ac464SStefano Babic }
2343b8ac464SStefano Babic }
2353b8ac464SStefano Babic
2363b8ac464SStefano Babic if (cRetCode < 0) {
2373b8ac464SStefano Babic return VME_VERSION_FAILURE;
2383b8ac464SStefano Babic }
2393b8ac464SStefano Babic
2403b8ac464SStefano Babic printf("VME file checked: starting downloading to FPGA\n");
2413b8ac464SStefano Babic
2423b8ac464SStefano Babic ispVMStart();
2433b8ac464SStefano Babic
2443b8ac464SStefano Babic cRetCode = ispVMCode();
2453b8ac464SStefano Babic
2463b8ac464SStefano Babic ispVMEnd();
2473b8ac464SStefano Babic ispVMFreeMem();
2483b8ac464SStefano Babic puts("\n");
2493b8ac464SStefano Babic
2503b8ac464SStefano Babic if (cRetCode == 0 && expectedCRC != 0 &&
2513b8ac464SStefano Babic (expectedCRC != g_usCalculatedCRC)) {
2523b8ac464SStefano Babic printf("Expected CRC: 0x%.4X\n", expectedCRC);
2533b8ac464SStefano Babic printf("Calculated CRC: 0x%.4X\n", g_usCalculatedCRC);
2543b8ac464SStefano Babic return VME_CRC_FAILURE;
2553b8ac464SStefano Babic }
2563b8ac464SStefano Babic return cRetCode;
2573b8ac464SStefano Babic }
2583b8ac464SStefano Babic
lattice_validate(Lattice_desc * desc,const char * fn)2593b8ac464SStefano Babic static int lattice_validate(Lattice_desc *desc, const char *fn)
2603b8ac464SStefano Babic {
261472d5460SYork Sun int ret_val = false;
2623b8ac464SStefano Babic
2633b8ac464SStefano Babic if (desc) {
2643b8ac464SStefano Babic if ((desc->family > min_lattice_type) &&
2653b8ac464SStefano Babic (desc->family < max_lattice_type)) {
2663b8ac464SStefano Babic if ((desc->iface > min_lattice_iface_type) &&
2673b8ac464SStefano Babic (desc->iface < max_lattice_iface_type)) {
2683b8ac464SStefano Babic if (desc->size) {
269472d5460SYork Sun ret_val = true;
2703b8ac464SStefano Babic } else {
2713b8ac464SStefano Babic printf("%s: NULL part size\n", fn);
2723b8ac464SStefano Babic }
2733b8ac464SStefano Babic } else {
2743b8ac464SStefano Babic printf("%s: Invalid Interface type, %d\n",
2753b8ac464SStefano Babic fn, desc->iface);
2763b8ac464SStefano Babic }
2773b8ac464SStefano Babic } else {
2783b8ac464SStefano Babic printf("%s: Invalid family type, %d\n",
2793b8ac464SStefano Babic fn, desc->family);
2803b8ac464SStefano Babic }
2813b8ac464SStefano Babic } else {
2823b8ac464SStefano Babic printf("%s: NULL descriptor!\n", fn);
2833b8ac464SStefano Babic }
2843b8ac464SStefano Babic
2853b8ac464SStefano Babic return ret_val;
2863b8ac464SStefano Babic }
2873b8ac464SStefano Babic
lattice_load(Lattice_desc * desc,const void * buf,size_t bsize)288fb2d6efbSWolfgang Denk int lattice_load(Lattice_desc *desc, const void *buf, size_t bsize)
2893b8ac464SStefano Babic {
2903b8ac464SStefano Babic int ret_val = FPGA_FAIL;
2913b8ac464SStefano Babic
2923b8ac464SStefano Babic if (!lattice_validate(desc, (char *)__func__)) {
2933b8ac464SStefano Babic printf("%s: Invalid device descriptor\n", __func__);
2943b8ac464SStefano Babic } else {
2953b8ac464SStefano Babic pfns = desc->iface_fns;
2963b8ac464SStefano Babic
2973b8ac464SStefano Babic switch (desc->family) {
2983b8ac464SStefano Babic case Lattice_XP2:
2993b8ac464SStefano Babic fpga_image = buf;
3003b8ac464SStefano Babic read_bytes = 0;
3013b8ac464SStefano Babic bufsize = bsize;
3023b8ac464SStefano Babic debug("%s: Launching the Lattice ISPVME Loader:"
303b89c708bSMarek Vasut " addr %p size 0x%lx...\n",
3043b8ac464SStefano Babic __func__, fpga_image, bufsize);
3053b8ac464SStefano Babic ret_val = ispVM();
3063b8ac464SStefano Babic if (ret_val)
3073b8ac464SStefano Babic printf("%s: error %d downloading FPGA image\n",
3083b8ac464SStefano Babic __func__, ret_val);
3093b8ac464SStefano Babic else
3103b8ac464SStefano Babic puts("FPGA downloaded successfully\n");
3113b8ac464SStefano Babic break;
3123b8ac464SStefano Babic default:
3133b8ac464SStefano Babic printf("%s: Unsupported family type, %d\n",
3143b8ac464SStefano Babic __func__, desc->family);
3153b8ac464SStefano Babic }
3163b8ac464SStefano Babic }
3173b8ac464SStefano Babic
3183b8ac464SStefano Babic return ret_val;
3193b8ac464SStefano Babic }
3203b8ac464SStefano Babic
lattice_dump(Lattice_desc * desc,const void * buf,size_t bsize)321fb2d6efbSWolfgang Denk int lattice_dump(Lattice_desc *desc, const void *buf, size_t bsize)
3223b8ac464SStefano Babic {
3233b8ac464SStefano Babic puts("Dump not supported for Lattice FPGA\n");
3243b8ac464SStefano Babic
3253b8ac464SStefano Babic return FPGA_FAIL;
3263b8ac464SStefano Babic
3273b8ac464SStefano Babic }
3283b8ac464SStefano Babic
lattice_info(Lattice_desc * desc)3293b8ac464SStefano Babic int lattice_info(Lattice_desc *desc)
3303b8ac464SStefano Babic {
3313b8ac464SStefano Babic int ret_val = FPGA_FAIL;
3323b8ac464SStefano Babic
3333b8ac464SStefano Babic if (lattice_validate(desc, (char *)__func__)) {
3343b8ac464SStefano Babic printf("Family: \t");
3353b8ac464SStefano Babic switch (desc->family) {
3363b8ac464SStefano Babic case Lattice_XP2:
3373b8ac464SStefano Babic puts("XP2\n");
3383b8ac464SStefano Babic break;
3393b8ac464SStefano Babic /* Add new family types here */
3403b8ac464SStefano Babic default:
3413b8ac464SStefano Babic printf("Unknown family type, %d\n", desc->family);
3423b8ac464SStefano Babic }
3433b8ac464SStefano Babic
3443b8ac464SStefano Babic puts("Interface type:\t");
3453b8ac464SStefano Babic switch (desc->iface) {
3463b8ac464SStefano Babic case lattice_jtag_mode:
3473b8ac464SStefano Babic puts("JTAG Mode\n");
3483b8ac464SStefano Babic break;
3493b8ac464SStefano Babic /* Add new interface types here */
3503b8ac464SStefano Babic default:
3513b8ac464SStefano Babic printf("Unsupported interface type, %d\n", desc->iface);
3523b8ac464SStefano Babic }
3533b8ac464SStefano Babic
3543b8ac464SStefano Babic printf("Device Size: \t%d bytes\n",
3553b8ac464SStefano Babic desc->size);
3563b8ac464SStefano Babic
3573b8ac464SStefano Babic if (desc->iface_fns) {
3583b8ac464SStefano Babic printf("Device Function Table @ 0x%p\n",
3593b8ac464SStefano Babic desc->iface_fns);
3603b8ac464SStefano Babic switch (desc->family) {
3613b8ac464SStefano Babic case Lattice_XP2:
3623b8ac464SStefano Babic break;
3633b8ac464SStefano Babic /* Add new family types here */
3643b8ac464SStefano Babic default:
3653b8ac464SStefano Babic break;
3663b8ac464SStefano Babic }
3673b8ac464SStefano Babic } else {
3683b8ac464SStefano Babic puts("No Device Function Table.\n");
3693b8ac464SStefano Babic }
3703b8ac464SStefano Babic
3713b8ac464SStefano Babic if (desc->desc)
3723b8ac464SStefano Babic printf("Model: \t%s\n", desc->desc);
3733b8ac464SStefano Babic
3743b8ac464SStefano Babic ret_val = FPGA_SUCCESS;
3753b8ac464SStefano Babic } else {
3763b8ac464SStefano Babic printf("%s: Invalid device descriptor\n", __func__);
3773b8ac464SStefano Babic }
3783b8ac464SStefano Babic
3793b8ac464SStefano Babic return ret_val;
3803b8ac464SStefano Babic }
381