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