From 3b8ac464f25581a7d22b303a9154c05e0c7f40a8 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Tue, 29 Jun 2010 11:47:48 +0200 Subject: FPGA: add support for downloading Lattice bitstream The patch adds support to load a Lattice's bitstream image (called VME file) into a Lattice FPGA. The code containing the state machine delivered as part of Lattice's ispVMtools is integrated. The FPGA is programmed using the JTAG interface. The board maintainer must provide accessors to drive the JTAG signals TCK, TMS, TDI and to get the value of the input signal TDO. Signed-off-by: Stefano Babic diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index 52d8e24..9ecdc5e 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -31,6 +31,7 @@ COBJS-$(CONFIG_FPGA_SPARTAN2) += spartan2.o COBJS-$(CONFIG_FPGA_SPARTAN3) += spartan3.o COBJS-$(CONFIG_FPGA_VIRTEX2) += virtex2.o COBJS-$(CONFIG_FPGA_XILINX) += xilinx.o +COBJS-$(CONFIG_FPGA_LATTICE) += ivm_core.o lattice.o ifdef CONFIG_FPGA_ALTERA COBJS-y += altera.o COBJS-$(CONFIG_FPGA_ACEX1K) += ACEX1K.o diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c index 5659517..e41e728 100644 --- a/drivers/fpga/fpga.c +++ b/drivers/fpga/fpga.c @@ -28,6 +28,7 @@ #include /* core U-Boot definitions */ #include /* xilinx specific definitions */ #include /* altera specific definitions */ +#include #if 0 #define FPGA_DEBUG /* define FPGA_DEBUG to get debug messages */ @@ -139,6 +140,10 @@ static int fpga_dev_info( int devnum ) fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); #endif break; + case fpga_lattice: + printf("Lattice Device\nDescriptor @ 0x%p\n", desc); + ret_val = lattice_info(desc->devdesc); + break; default: printf( "%s: Invalid or unsupported device type %d\n", __FUNCTION__, desc->devtype ); @@ -224,6 +229,9 @@ int fpga_load( int devnum, void *buf, size_t bsize ) fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); #endif break; + case fpga_lattice: + ret_val = lattice_load(desc->devdesc, buf, bsize); + break; default: printf( "%s: Invalid or unsupported device type %d\n", __FUNCTION__, desc->devtype ); @@ -257,6 +265,9 @@ int fpga_dump( int devnum, void *buf, size_t bsize ) fpga_no_sup( (char *)__FUNCTION__, "Altera devices" ); #endif break; + case fpga_lattice: + ret_val = lattice_dump(desc->devdesc, buf, bsize); + break; default: printf( "%s: Invalid or unsupported device type %d\n", __FUNCTION__, desc->devtype ); diff --git a/drivers/fpga/ivm_core.c b/drivers/fpga/ivm_core.c new file mode 100755 index 0000000..2b5a485 --- /dev/null +++ b/drivers/fpga/ivm_core.c @@ -0,0 +1,3167 @@ +/* + * Porting to u-boot: + * + * (C) Copyright 2010 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de. + * + * Lattice ispVME Embedded code to load Lattice's FPGA: + * + * Copyright 2009 Lattice Semiconductor Corp. + * + * ispVME Embedded allows programming of Lattice's suite of FPGA + * devices on embedded systems through the JTAG port. The software + * is distributed in source code form and is open to re - distribution + * and modification where applicable. + * + * Revision History of ivm_core.c module: + * 4/25/06 ht Change some variables from unsigned short or int + * to long int to make the code compiler independent. + * 5/24/06 ht Support using RESET (TRST) pin as a special purpose + * control pin such as triggering the loading of known + * state exit. + * 3/6/07 ht added functions to support output to terminals + * + * 09/11/07 NN Type cast mismatch variables + * Moved the sclock() function to hardware.c + * 08/28/08 NN Added Calculate checksum support. + * 4/1/09 Nguyen replaced the recursive function call codes on + * the ispVMLCOUNT function + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#define vme_out_char(c) printf("%c", c) +#define vme_out_hex(c) printf("%x", c) +#define vme_out_string(s) printf("%s", s) + +/* + * + * Global variables used to specify the flow control and data type. + * + * g_usFlowControl: flow control register. Each bit in the + * register can potentially change the + * personality of the embedded engine. + * g_usDataType: holds the data type of the current row. + * + */ + +static unsigned short g_usFlowControl; +unsigned short g_usDataType; + +/* + * + * Global variables used to specify the ENDDR and ENDIR. + * + * g_ucEndDR: the state that the device goes to after SDR. + * g_ucEndIR: the state that the device goes to after SIR. + * + */ + +unsigned char g_ucEndDR = DRPAUSE; +unsigned char g_ucEndIR = IRPAUSE; + +/* + * + * Global variables used to support header/trailer. + * + * g_usHeadDR: the number of lead devices in bypass. + * g_usHeadIR: the sum of IR length of lead devices. + * g_usTailDR: the number of tail devices in bypass. + * g_usTailIR: the sum of IR length of tail devices. + * + */ + +static unsigned short g_usHeadDR; +static unsigned short g_usHeadIR; +static unsigned short g_usTailDR; +static unsigned short g_usTailIR; + +/* + * + * Global variable to store the number of bits of data or instruction + * to be shifted into or out from the device. + * + */ + +static unsigned short g_usiDataSize; + +/* + * + * Stores the frequency. Default to 1 MHz. + * + */ + +static int g_iFrequency = 1000; + +/* + * + * Stores the maximum amount of ram needed to hold a row of data. + * + */ + +static unsigned short g_usMaxSize; + +/* + * + * Stores the LSH or RSH value. + * + */ + +static unsigned short g_usShiftValue; + +/* + * + * Stores the current repeat loop value. + * + */ + +static unsigned short g_usRepeatLoops; + +/* + * + * Stores the current vendor. + * + */ + +static signed char g_cVendor = LATTICE; + +/* + * + * Stores the VME file CRC. + * + */ + +unsigned short g_usCalculatedCRC; + +/* + * + * Stores the Device Checksum. + * + */ +/* 08/28/08 NN Added Calculate checksum support. */ +unsigned long g_usChecksum; +static unsigned int g_uiChecksumIndex; + +/* + * + * Stores the current state of the JTAG state machine. + * + */ + +static signed char g_cCurrentJTAGState; + +/* + * + * Global variables used to support looping. + * + * g_pucHeapMemory: holds the entire repeat loop. + * g_iHeapCounter: points to the current byte in the repeat loop. + * g_iHEAPSize: the current size of the repeat in bytes. + * + */ + +unsigned char *g_pucHeapMemory; +unsigned short g_iHeapCounter; +unsigned short g_iHEAPSize; +static unsigned short previous_size; + +/* + * + * Global variables used to support intelligent programming. + * + * g_usIntelDataIndex: points to the current byte of the + * intelligent buffer. + * g_usIntelBufferSize: holds the size of the intelligent + * buffer. + * + */ + +unsigned short g_usIntelDataIndex; +unsigned short g_usIntelBufferSize; + +/* + * + * Supported VME versions. + * + */ + +const char *const g_szSupportedVersions[] = { + "__VME2.0", "__VME3.0", "____12.0", "____12.1", 0}; + +/* + * + * Holds the maximum size of each respective buffer. These variables are used + * to write the HEX files when converting VME to HEX. + * +*/ + +static unsigned short g_usTDOSize; +static unsigned short g_usMASKSize; +static unsigned short g_usTDISize; +static unsigned short g_usDMASKSize; +static unsigned short g_usLCOUNTSize; +static unsigned short g_usHDRSize; +static unsigned short g_usTDRSize; +static unsigned short g_usHIRSize; +static unsigned short g_usTIRSize; +static unsigned short g_usHeapSize; + +/* + * + * Global variables used to store data. + * + * g_pucOutMaskData: local RAM to hold one row of MASK data. + * g_pucInData: local RAM to hold one row of TDI data. + * g_pucOutData: local RAM to hold one row of TDO data. + * g_pucHIRData: local RAM to hold the current SIR header. + * g_pucTIRData: local RAM to hold the current SIR trailer. + * g_pucHDRData: local RAM to hold the current SDR header. + * g_pucTDRData: local RAM to hold the current SDR trailer. + * g_pucIntelBuffer: local RAM to hold the current intelligent buffer + * g_pucOutDMaskData: local RAM to hold one row of DMASK data. + * + */ + +unsigned char *g_pucOutMaskData = NULL, + *g_pucInData = NULL, + *g_pucOutData = NULL, + *g_pucHIRData = NULL, + *g_pucTIRData = NULL, + *g_pucHDRData = NULL, + *g_pucTDRData = NULL, + *g_pucIntelBuffer = NULL, + *g_pucOutDMaskData = NULL; + +/* + * + * JTAG state machine transition table. + * + */ + +struct { + unsigned char CurState; /* From this state */ + unsigned char NextState; /* Step to this state */ + unsigned char Pattern; /* The tragetory of TMS */ + unsigned char Pulses; /* The number of steps */ +} g_JTAGTransistions[25] = { +{ RESET, RESET, 0xFC, 6 }, /* Transitions from RESET */ +{ RESET, IDLE, 0x00, 1 }, +{ RESET, DRPAUSE, 0x50, 5 }, +{ RESET, IRPAUSE, 0x68, 6 }, +{ IDLE, RESET, 0xE0, 3 }, /* Transitions from IDLE */ +{ IDLE, DRPAUSE, 0xA0, 4 }, +{ IDLE, IRPAUSE, 0xD0, 5 }, +{ DRPAUSE, RESET, 0xF8, 5 }, /* Transitions from DRPAUSE */ +{ DRPAUSE, IDLE, 0xC0, 3 }, +{ DRPAUSE, IRPAUSE, 0xF4, 7 }, +{ DRPAUSE, DRPAUSE, 0xE8, 6 },/* 06/14/06 Support POLL STATUS LOOP*/ +{ IRPAUSE, RESET, 0xF8, 5 }, /* Transitions from IRPAUSE */ +{ IRPAUSE, IDLE, 0xC0, 3 }, +{ IRPAUSE, DRPAUSE, 0xE8, 6 }, +{ DRPAUSE, SHIFTDR, 0x80, 2 }, /* Extra transitions using SHIFTDR */ +{ IRPAUSE, SHIFTDR, 0xE0, 5 }, +{ SHIFTDR, DRPAUSE, 0x80, 2 }, +{ SHIFTDR, IDLE, 0xC0, 3 }, +{ IRPAUSE, SHIFTIR, 0x80, 2 },/* Extra transitions using SHIFTIR */ +{ SHIFTIR, IRPAUSE, 0x80, 2 }, +{ SHIFTIR, IDLE, 0xC0, 3 }, +{ DRPAUSE, DRCAPTURE, 0xE0, 4 }, /* 11/15/05 Support DRCAPTURE*/ +{ DRCAPTURE, DRPAUSE, 0x80, 2 }, +{ IDLE, DRCAPTURE, 0x80, 2 }, +{ IRPAUSE, DRCAPTURE, 0xE0, 4 } +}; + +/* + * + * List to hold all LVDS pairs. + * + */ + +LVDSPair *g_pLVDSList; +unsigned short g_usLVDSPairCount; + +/* + * + * Function prototypes. + * + */ + +static signed char ispVMDataCode(void); +static long int ispVMDataSize(void); +static void ispVMData(unsigned char *Data); +static signed char ispVMShift(signed char Code); +static signed char ispVMAmble(signed char Code); +static signed char ispVMLoop(unsigned short a_usLoopCount); +static signed char ispVMBitShift(signed char mode, unsigned short bits); +static void ispVMComment(unsigned short a_usCommentSize); +static void ispVMHeader(unsigned short a_usHeaderSize); +static signed char ispVMLCOUNT(unsigned short a_usCountSize); +static void ispVMClocks(unsigned short Clocks); +static void ispVMBypass(signed char ScanType, unsigned short Bits); +static void ispVMStateMachine(signed char NextState); +static signed char ispVMSend(unsigned short int); +static signed char ispVMRead(unsigned short int); +static signed char ispVMReadandSave(unsigned short int); +static signed char ispVMProcessLVDS(unsigned short a_usLVDSCount); +static void ispVMMemManager(signed char types, unsigned short size); + +/* + * + * External variables and functions in hardware.c module + * + */ +static signed char g_cCurrentJTAGState; + +#ifdef DEBUG + +/* + * + * GetState + * + * Returns the state as a string based on the opcode. Only used + * for debugging purposes. + * + */ + +const char *GetState(unsigned char a_ucState) +{ + switch (a_ucState) { + case RESET: + return "RESET"; + case IDLE: + return "IDLE"; + case IRPAUSE: + return "IRPAUSE"; + case DRPAUSE: + return "DRPAUSE"; + case SHIFTIR: + return "SHIFTIR"; + case SHIFTDR: + return "SHIFTDR"; + case DRCAPTURE:/* 11/15/05 support DRCAPTURE*/ + return "DRCAPTURE"; + default: + break; + } + + return 0; +} + +/* + * + * PrintData + * + * Prints the data. Only used for debugging purposes. + * + */ + +void PrintData(unsigned short a_iDataSize, unsigned char *a_pucData) +{ + /* 09/11/07 NN added local variables initialization */ + unsigned short usByteSize = 0; + unsigned short usBitIndex = 0; + signed short usByteIndex = 0; + unsigned char ucByte = 0; + unsigned char ucFlipByte = 0; + + if (a_iDataSize % 8) { + /* 09/11/07 NN Type cast mismatch variables */ + usByteSize = (unsigned short)(a_iDataSize / 8 + 1); + } else { + /* 09/11/07 NN Type cast mismatch variables */ + usByteSize = (unsigned short)(a_iDataSize / 8); + } + puts("("); + /* 09/11/07 NN Type cast mismatch variables */ + for (usByteIndex = (signed short)(usByteSize - 1); + usByteIndex >= 0; usByteIndex--) { + ucByte = a_pucData[usByteIndex]; + ucFlipByte = 0x00; + + /* + * + * Flip each byte. + * + */ + + for (usBitIndex = 0; usBitIndex < 8; usBitIndex++) { + ucFlipByte <<= 1; + if (ucByte & 0x1) { + ucFlipByte |= 0x1; + } + + ucByte >>= 1; + } + + /* + * + * Print the flipped byte. + * + */ + + printf("%.02X", ucFlipByte); + if ((usByteSize - usByteIndex) % 40 == 39) { + puts("\n\t\t"); + } + if (usByteIndex < 0) + break; + } + puts(")"); +} +#endif /* DEBUG */ + +void ispVMMemManager(signed char cTarget, unsigned short usSize) +{ + switch (cTarget) { + case XTDI: + case TDI: + if (g_pucInData != NULL) { + if (previous_size == usSize) {/*memory exist*/ + break; + } else { + free(g_pucInData); + g_pucInData = NULL; + } + } + g_pucInData = (unsigned char *) malloc(usSize / 8 + 2); + previous_size = usSize; + case XTDO: + case TDO: + if (g_pucOutData != NULL) { + if (previous_size == usSize) { /*already exist*/ + break; + } else { + free(g_pucOutData); + g_pucOutData = NULL; + } + } + g_pucOutData = (unsigned char *) malloc(usSize / 8 + 2); + previous_size = usSize; + break; + case MASK: + if (g_pucOutMaskData != NULL) { + if (previous_size == usSize) {/*already allocated*/ + break; + } else { + free(g_pucOutMaskData); + g_pucOutMaskData = NULL; + } + } + g_pucOutMaskData = (unsigned char *) malloc(usSize / 8 + 2); + previous_size = usSize; + break; + case HIR: + if (g_pucHIRData != NULL) { + free(g_pucHIRData); + g_pucHIRData = NULL; + } + g_pucHIRData = (unsigned char *) malloc(usSize / 8 + 2); + break; + case TIR: + if (g_pucTIRData != NULL) { + free(g_pucTIRData); + g_pucTIRData = NULL; + } + g_pucTIRData = (unsigned char *) malloc(usSize / 8 + 2); + break; + case HDR: + if (g_pucHDRData != NULL) { + free(g_pucHDRData); + g_pucHDRData = NULL; + } + g_pucHDRData = (unsigned char *) malloc(usSize / 8 + 2); + break; + case TDR: + if (g_pucTDRData != NULL) { + free(g_pucTDRData); + g_pucTDRData = NULL; + } + g_pucTDRData = (unsigned char *) malloc(usSize / 8 + 2); + break; + case HEAP: + if (g_pucHeapMemory != NULL) { + free(g_pucHeapMemory); + g_pucHeapMemory = NULL; + } + g_pucHeapMemory = (unsigned char *) malloc(usSize + 2); + break; + case DMASK: + if (g_pucOutDMaskData != NULL) { + if (previous_size == usSize) { /*already allocated*/ + break; + } else { + free(g_pucOutDMaskData); + g_pucOutDMaskData = NULL; + } + } + g_pucOutDMaskData = (unsigned char *) malloc(usSize / 8 + 2); + previous_size = usSize; + break; + case LHEAP: + if (g_pucIntelBuffer != NULL) { + free(g_pucIntelBuffer); + g_pucIntelBuffer = NULL; + } + g_pucIntelBuffer = (unsigned char *) malloc(usSize + 2); + break; + case LVDS: + if (g_pLVDSList != NULL) { + free(g_pLVDSList); + g_pLVDSList = NULL; + } + g_pLVDSList = (LVDSPair *) malloc(usSize * sizeof(LVDSPair)); + if (g_pLVDSList) + memset(g_pLVDSList, 0, usSize * sizeof(LVDSPair)); + break; + default: + return; + } +} + +void ispVMFreeMem(void) +{ + if (g_pucHeapMemory != NULL) { + free(g_pucHeapMemory); + g_pucHeapMemory = NULL; + } + + if (g_pucOutMaskData != NULL) { + free(g_pucOutMaskData); + g_pucOutMaskData = NULL; + } + + if (g_pucInData != NULL) { + free(g_pucInData); + g_pucInData = NULL; + } + + if (g_pucOutData != NULL) { + free(g_pucOutData); + g_pucOutData = NULL; + } + + if (g_pucHIRData != NULL) { + free(g_pucHIRData); + g_pucHIRData = NULL; + } + + if (g_pucTIRData != NULL) { + free(g_pucTIRData); + g_pucTIRData = NULL; + } + + if (g_pucHDRData != NULL) { + free(g_pucHDRData); + g_pucHDRData = NULL; + } + + if (g_pucTDRData != NULL) { + free(g_pucTDRData); + g_pucTDRData = NULL; + } + + if (g_pucOutDMaskData != NULL) { + free(g_pucOutDMaskData); + g_pucOutDMaskData = NULL; + } + + if (g_pucIntelBuffer != NULL) { + free(g_pucIntelBuffer); + g_pucIntelBuffer = NULL; + } + + if (g_pLVDSList != NULL) { + free(g_pLVDSList); + g_pLVDSList = NULL; + } +} + + +/* + * + * ispVMDataSize + * + * Returns a VME-encoded number, usually used to indicate the + * bit length of an SIR/SDR command. + * + */ + +long int ispVMDataSize() +{ + /* 09/11/07 NN added local variables initialization */ + long int iSize = 0; + signed char cCurrentByte = 0; + signed char cIndex = 0; + cIndex = 0; + while ((cCurrentByte = GetByte()) & 0x80) { + iSize |= ((long int) (cCurrentByte & 0x7F)) << cIndex; + cIndex += 7; + } + iSize |= ((long int) (cCurrentByte & 0x7F)) << cIndex; + return iSize; +} + +/* + * + * ispVMCode + * + * This is the heart of the embedded engine. All the high-level opcodes + * are extracted here. Once they have been identified, then it + * will call other functions to handle the processing. + * + */ + +signed char ispVMCode() +{ + /* 09/11/07 NN added local variables initialization */ + unsigned short iRepeatSize = 0; + signed char cOpcode = 0; + signed char cRetCode = 0; + unsigned char ucState = 0; + unsigned short usDelay = 0; + unsigned short usToggle = 0; + unsigned char usByte = 0; + + /* + * + * Check the compression flag only if this is the first time + * this function is entered. Do not check the compression flag if + * it is being called recursively from other functions within + * the embedded engine. + * + */ + + if (!(g_usDataType & LHEAP_IN) && !(g_usDataType & HEAP_IN)) { + usByte = GetByte(); + if (usByte == 0xf1) { + g_usDataType |= COMPRESS; + } else if (usByte == 0xf2) { + g_usDataType &= ~COMPRESS; + } else { + return VME_INVALID_FILE; + } + } + + /* + * + * Begin looping through all the VME opcodes. + * + */ + + while ((cOpcode = GetByte()) >= 0) { + + switch (cOpcode) { + case STATE: + + /* + * Step the JTAG state machine. + */ + + ucState = GetByte(); + + /* + * Step the JTAG state machine to DRCAPTURE + * to support Looping. + */ + + if ((g_usDataType & LHEAP_IN) && + (ucState == DRPAUSE) && + (g_cCurrentJTAGState == ucState)) { + ispVMStateMachine(DRCAPTURE); + } + + ispVMStateMachine(ucState); + +#ifdef DEBUG + if (g_usDataType & LHEAP_IN) { + debug("LDELAY %s ", GetState(ucState)); + } else { + debug("STATE %s;\n", GetState(ucState)); + } +#endif /* DEBUG */ + break; + case SIR: + case SDR: + case XSDR: + +#ifdef DEBUG + switch (cOpcode) { + case SIR: + puts("SIR "); + break; + case SDR: + case XSDR: + if (g_usDataType & LHEAP_IN) { + puts("LSDR "); + } else { + puts("SDR "); + } + break; + } +#endif /* DEBUG */ + /* + * + * Shift in data into the device. + * + */ + + cRetCode = ispVMShift(cOpcode); + if (cRetCode != 0) { + return cRetCode; + } + break; + case WAIT: + + /* + * + * Observe delay. + * + */ + + /* 09/11/07 NN Type cast mismatch variables */ + usDelay = (unsigned short) ispVMDataSize(); + ispVMDelay(usDelay); + +#ifdef DEBUG + if (usDelay & 0x8000) { + + /* + * Since MSB is set, the delay time must be + * decoded to millisecond. The SVF2VME encodes + * the MSB to represent millisecond. + */ + + usDelay &= ~0x8000; + if (g_usDataType & LHEAP_IN) { + printf("%.2E SEC;\n", + (float) usDelay / 1000); + } else { + printf("RUNTEST %.2E SEC;\n", + (float) usDelay / 1000); + } + } else { + /* + * Since MSB is not set, the delay time + * is given as microseconds. + */ + + if (g_usDataType & LHEAP_IN) { + printf("%.2E SEC;\n", + (float) usDelay / 1000000); + } else { + printf("RUNTEST %.2E SEC;\n", + (float) usDelay / 1000000); + } + } +#endif /* DEBUG */ + break; + case TCK: + + /* + * Issue clock toggles. + */ + + /* 09/11/07 NN Type cast mismatch variables */ + usToggle = (unsigned short) ispVMDataSize(); + ispVMClocks(usToggle); + +#ifdef DEBUG + printf("RUNTEST %d TCK;\n", usToggle); +#endif /* DEBUG */ + break; + case ENDDR: + + /* + * + * Set the ENDDR. + * + */ + + g_ucEndDR = GetByte(); + +#ifdef DEBUG + printf("ENDDR %s;\n", GetState(g_ucEndDR)); +#endif /* DEBUG */ + break; + case ENDIR: + + /* + * + * Set the ENDIR. + * + */ + + g_ucEndIR = GetByte(); + +#ifdef DEBUG + printf("ENDIR %s;\n", GetState(g_ucEndIR)); +#endif /* DEBUG */ + break; + case HIR: + case TIR: + case HDR: + case TDR: + +#ifdef DEBUG + switch (cOpcode) { + case HIR: + puts("HIR "); + break; + case TIR: + puts("TIR "); + break; + case HDR: + puts("HDR "); + break; + case TDR: + puts("TDR "); + break; + } +#endif /* DEBUG */ + /* + * Set the header/trailer of the device in order + * to bypass + * successfully. + */ + + cRetCode = ispVMAmble(cOpcode); + if (cRetCode != 0) { + return cRetCode; + } + +#ifdef DEBUG + puts(";\n"); +#endif /* DEBUG */ + break; + case MEM: + + /* + * The maximum RAM required to support + * processing one row of the VME file. + */ + + /* 09/11/07 NN Type cast mismatch variables */ + g_usMaxSize = (unsigned short) ispVMDataSize(); + +#ifdef DEBUG + printf("// MEMSIZE %d\n", g_usMaxSize); +#endif /* DEBUG */ + break; + case VENDOR: + + /* + * + * Set the VENDOR type. + * + */ + + cOpcode = GetByte(); + switch (cOpcode) { + case LATTICE: +#ifdef DEBUG + puts("// VENDOR LATTICE\n"); +#endif /* DEBUG */ + g_cVendor = LATTICE; + break; + case ALTERA: +#ifdef DEBUG + puts("// VENDOR ALTERA\n"); +#endif /* DEBUG */ + g_cVendor = ALTERA; + break; + case XILINX: +#ifdef DEBUG + puts("// VENDOR XILINX\n"); +#endif /* DEBUG */ + g_cVendor = XILINX; + break; + default: + break; + } + break; + case SETFLOW: + + /* + * Set the flow control. Flow control determines + * the personality of the embedded engine. + */ + + /* 09/11/07 NN Type cast mismatch variables */ + g_usFlowControl |= (unsigned short) ispVMDataSize(); + break; + case RESETFLOW: + + /* + * + * Unset the flow control. + * + */ + + /* 09/11/07 NN Type cast mismatch variables */ + g_usFlowControl &= (unsigned short) ~(ispVMDataSize()); + break; + case HEAP: + + /* + * + * Allocate heap size to store loops. + * + */ + + cRetCode = GetByte(); + if (cRetCode != SECUREHEAP) { + return VME_INVALID_FILE; + } + /* 09/11/07 NN Type cast mismatch variables */ + g_iHEAPSize = (unsigned short) ispVMDataSize(); + + /* + * Store the maximum size of the HEAP buffer. + * Used to convert VME to HEX. + */ + + if (g_iHEAPSize > g_usHeapSize) { + g_usHeapSize = g_iHEAPSize; + } + + ispVMMemManager(HEAP, (unsigned short) g_iHEAPSize); + break; + case REPEAT: + + /* + * + * Execute loops. + * + */ + + g_usRepeatLoops = 0; + + /* 09/11/07 NN Type cast mismatch variables */ + iRepeatSize = (unsigned short) ispVMDataSize(); + + cRetCode = ispVMLoop((unsigned short) iRepeatSize); + if (cRetCode != 0) { + return cRetCode; + } + break; + case ENDLOOP: + + /* + * + * Exit point from processing loops. + * + */ + + return cRetCode; + case ENDVME: + + /* + * The only valid exit point that indicates + * end of programming. + */ + + return cRetCode; + case SHR: + + /* + * + * Right-shift address. + * + */ + + g_usFlowControl |= SHIFTRIGHT; + + /* 09/11/07 NN Type cast mismatch variables */ + g_usShiftValue = (unsigned short) (g_usRepeatLoops * + (unsigned short)GetByte()); + break; + case SHL: + + /* + * Left-shift address. + */ + + g_usFlowControl |= SHIFTLEFT; + + /* 09/11/07 NN Type cast mismatch variables */ + g_usShiftValue = (unsigned short) (g_usRepeatLoops * + (unsigned short)GetByte()); + break; + case FREQUENCY: + + /* + * + * Set the frequency. + * + */ + + /* 09/11/07 NN Type cast mismatch variables */ + g_iFrequency = (int) (ispVMDataSize() / 1000); + if (g_iFrequency == 1) + g_iFrequency = 1000; + +#ifdef DEBUG + printf("FREQUENCY %.2E HZ;\n", + (float) g_iFrequency * 1000); +#endif /* DEBUG */ + break; + case LCOUNT: + + /* + * + * Process LCOUNT command. + * + */ + + cRetCode = ispVMLCOUNT((unsigned short)ispVMDataSize()); + if (cRetCode != 0) { + return cRetCode; + } + break; + case VUES: + + /* + * + * Set the flow control to verify USERCODE. + * + */ + + g_usFlowControl |= VERIFYUES; + break; + case COMMENT: + + /* + * + * Display comment. + * + */ + + ispVMComment((unsigned short) ispVMDataSize()); + break; + case LVDS: + + /* + * + * Process LVDS command. + * + */ + + ispVMProcessLVDS((unsigned short) ispVMDataSize()); + break; + case HEADER: + + /* + * + * Discard header. + * + */ + + ispVMHeader((unsigned short) ispVMDataSize()); + break; + /* 03/14/06 Support Toggle ispENABLE signal*/ + case ispEN: + ucState = GetByte(); + if ((ucState == ON) || (ucState == 0x01)) + writePort(g_ucPinENABLE, 0x01); + else + writePort(g_ucPinENABLE, 0x00); + ispVMDelay(1); + break; + /* 05/24/06 support Toggle TRST pin*/ + case TRST: + ucState = GetByte(); + if (ucState == 0x01) + writePort(g_ucPinTRST, 0x01); + else + writePort(g_ucPinTRST, 0x00); + ispVMDelay(1); + break; + default: + + /* + * + * Invalid opcode encountered. + * + */ + +#ifdef DEBUG + printf("\nINVALID OPCODE: 0x%.2X\n", cOpcode); +#endif /* DEBUG */ + + return VME_INVALID_FILE; + } + } + + /* + * + * Invalid exit point. Processing the token 'ENDVME' is the only + * valid way to exit the embedded engine. + * + */ + + return VME_INVALID_FILE; +} + +/* + * + * ispVMDataCode + * + * Processes the TDI/TDO/MASK/DMASK etc of an SIR/SDR command. + * + */ + +signed char ispVMDataCode() +{ + /* 09/11/07 NN added local variables initialization */ + signed char cDataByte = 0; + signed char siDataSource = 0; /*source of data from file by default*/ + + if (g_usDataType & HEAP_IN) { + siDataSource = 1; /*the source of data from memory*/ + } + + /* + * + * Clear the data type register. + * + **/ + + g_usDataType &= ~(MASK_DATA + TDI_DATA + + TDO_DATA + DMASK_DATA + CMASK_DATA); + + /* + * Iterate through SIR/SDR command and look for TDI, + * TDO, MASK, etc. + */ + + while ((cDataByte = GetByte()) >= 0) { + ispVMMemManager(cDataByte, g_usMaxSize); + switch (cDataByte) { + case TDI: + + /* + * Store the maximum size of the TDI buffer. + * Used to convert VME to HEX. + */ + + if (g_usiDataSize > g_usTDISize) { + g_usTDISize = g_usiDataSize; + } + /* + * Updated data type register to indicate that + * TDI data is currently being used. Process the + * data in the VME file into the TDI buffer. + */ + + g_usDataType |= TDI_DATA; + ispVMData(g_pucInData); + break; + case XTDO: + + /* + * Store the maximum size of the TDO buffer. + * Used to convert VME to HEX. + */ + + if (g_usiDataSize > g_usTDOSize) { + g_usTDOSize = g_usiDataSize; + } + + /* + * Updated data type register to indicate that + * TDO data is currently being used. + */ + + g_usDataType |= TDO_DATA; + break; + case TDO: + + /* + * Store the maximum size of the TDO buffer. + * Used to convert VME to HEX. + */ + + if (g_usiDataSize > g_usTDOSize) { + g_usTDOSize = g_usiDataSize; + } + + /* + * Updated data type register to indicate + * that TDO data is currently being used. + * Process the data in the VME file into the + * TDO buffer. + */ + + g_usDataType |= TDO_DATA; + ispVMData(g_pucOutData); + break; + case MASK: + + /* + * Store the maximum size of the MASK buffer. + * Used to convert VME to HEX. + */ + + if (g_usiDataSize > g_usMASKSize) { + g_usMASKSize = g_usiDataSize; + } + + /* + * Updated data type register to indicate that + * MASK data is currently being used. Process + * the data in the VME file into the MASK buffer + */ + + g_usDataType |= MASK_DATA; + ispVMData(g_pucOutMaskData); + break; + case DMASK: + + /* + * Store the maximum size of the DMASK buffer. + * Used to convert VME to HEX. + */ + + if (g_usiDataSize > g_usDMASKSize) { + g_usDMASKSize = g_usiDataSize; + } + + /* + * Updated data type register to indicate that + * DMASK data is currently being used. Process + * the data in the VME file into the DMASK + * buffer. + */ + + g_usDataType |= DMASK_DATA; + ispVMData(g_pucOutDMaskData); + break; + case CMASK: + + /* + * Updated data type register to indicate that + * MASK data is currently being used. Process + * the data in the VME file into the MASK buffer + */ + + g_usDataType |= CMASK_DATA; + ispVMData(g_pucOutMaskData); + break; + case CONTINUE: + return 0; + default: + /* + * Encountered invalid opcode. + */ + return VME_INVALID_FILE; + } + + switch (cDataByte) { + case TDI: + + /* + * Left bit shift. Used when performing + * algorithm looping. + */ + + if (g_usFlowControl & SHIFTLEFT) { + ispVMBitShift(SHL, g_usShiftValue); + g_usFlowControl &= ~SHIFTLEFT; + } + + /* + * Right bit shift. Used when performing + * algorithm looping. + */ + + if (g_usFlowControl & SHIFTRIGHT) { + ispVMBitShift(SHR, g_usShiftValue); + g_usFlowControl &= ~SHIFTRIGHT; + } + default: + break; + } + + if (siDataSource) { + g_usDataType |= HEAP_IN; /*restore from memory*/ + } + } + + if (siDataSource) { /*fetch data from heap memory upon return*/ + g_usDataType |= HEAP_IN; + } + + if (cDataByte < 0) { + + /* + * Encountered invalid opcode. + */ + + return VME_INVALID_FILE; + } else { + return 0; + } +} + +/* + * + * ispVMData + * Extract one row of data operand from the current data type opcode. Perform + * the decompression if necessary. Extra RAM is not required for the + * decompression process. The decompression scheme employed in this module + * is on row by row basis. The format of the data stream: + * [compression code][compressed data stream] + * 0x00 --No compression + * 0x01 --Compress by 0x00. + * Example: + * Original stream: 0x000000000000000000000001 + * Compressed stream: 0x01000901 + * Detail: 0x01 is the code, 0x00 is the key, + * 0x09 is the count of 0x00 bytes, + * 0x01 is the uncompressed byte. + * 0x02 --Compress by 0xFF. + * Example: + * Original stream: 0xFFFFFFFFFFFFFFFFFFFFFF01 + * Compressed stream: 0x02FF0901 + * Detail: 0x02 is the code, 0xFF is the key, + * 0x09 is the count of 0xFF bytes, + * 0x01 is the uncompressed byte. + * 0x03 + * : : + * 0xFE -- Compress by nibble blocks. + * Example: + * Original stream: 0x84210842108421084210 + * Compressed stream: 0x0584210 + * Detail: 0x05 is the code, means 5 nibbles block. + * 0x84210 is the 5 nibble blocks. + * The whole row is 80 bits given by g_usiDataSize. + * The number of times the block repeat itself + * is found by g_usiDataSize/(4*0x05) which is 4. + * 0xFF -- Compress by the most frequently happen byte. + * Example: + * Original stream: 0x04020401030904040404 + * Compressed stream: 0xFF04(0,1,0x02,0,1,0x01,1,0x03,1,0x09,0,0,0) + * or: 0xFF044090181C240 + * Detail: 0xFF is the code, 0x04 is the key. + * a bit of 0 represent the key shall be put into + * the current bit position and a bit of 1 + * represent copying the next of 8 bits of data + * in. + * + */ + +void ispVMData(unsigned char *ByteData) +{ + /* 09/11/07 NN added local variables initialization */ + unsigned short size = 0; + unsigned short i, j, m, getData = 0; + unsigned char cDataByte = 0; + unsigned char compress = 0; + unsigned short FFcount = 0; + unsigned char compr_char = 0xFF; + unsigned short index = 0; + signed char compression = 0; + + /*convert number in bits to bytes*/ + if (g_usiDataSize % 8 > 0) { + /* 09/11/07 NN Type cast mismatch variables */ + size = (unsigned short)(g_usiDataSize / 8 + 1); + } else { + /* 09/11/07 NN Type cast mismatch variables */ + size = (unsigned short)(g_usiDataSize / 8); + } + + /* + * If there is compression, then check if compress by key + * of 0x00 or 0xFF or by other keys or by nibble blocks + */ + + if (g_usDataType & COMPRESS) { + compression = 1; + compress = GetByte(); + if ((compress == VAR) && (g_usDataType & HEAP_IN)) { + getData = 1; + g_usDataType &= ~(HEAP_IN); + compress = GetByte(); + } + + switch (compress) { + case 0x00: + /* No compression */ + compression = 0; + break; + case 0x01: + /* Compress by byte 0x00 */ + compr_char = 0x00; + break; + case 0x02: + /* Compress by byte 0xFF */ + compr_char = 0xFF; + break; + case 0xFF: + /* Huffman encoding */ + compr_char = GetByte(); + i = 8; + for (index = 0; index < size; index++) { + ByteData[index] = 0x00; + if (i > 7) { + cDataByte = GetByte(); + i = 0; + } + if ((cDataByte << i++) & 0x80) + m = 8; + else { + ByteData[index] = compr_char; + m = 0; + } + + for (j = 0; j < m; j++) { + if (i > 7) { + cDataByte = GetByte(); + i = 0; + } + ByteData[index] |= + ((cDataByte << i++) & 0x80) >> j; + } + } + size = 0; + break; + default: + for (index = 0; index < size; index++) + ByteData[index] = 0x00; + for (index = 0; index < compress; index++) { + if (index % 2 == 0) + cDataByte = GetByte(); + for (i = 0; i < size * 2 / compress; i++) { + j = (unsigned short)(index + + (i * (unsigned short)compress)); + /*clear the nibble to zero first*/ + if (j%2) { + if (index % 2) + ByteData[j/2] |= + cDataByte & 0xF; + else + ByteData[j/2] |= + cDataByte >> 4; + } else { + if (index % 2) + ByteData[j/2] |= + cDataByte << 4; + else + ByteData[j/2] |= + cDataByte & 0xF0; + } + } + } + size = 0; + break; + } + } + + FFcount = 0; + + /* Decompress by byte 0x00 or 0xFF */ + for (index = 0; index < size; index++) { + if (FFcount <= 0) { + cDataByte = GetByte(); + if ((cDataByte == VAR) && (g_usDataType&HEAP_IN) && + !getData && !(g_usDataType&COMPRESS)) { + getData = 1; + g_usDataType &= ~(HEAP_IN); + cDataByte = GetByte(); + } + ByteData[index] = cDataByte; + if ((compression) && (cDataByte == compr_char)) + /* 09/11/07 NN Type cast mismatch variables */ + FFcount = (unsigned short) ispVMDataSize(); + /*The number of 0xFF or 0x00 bytes*/ + } else { + FFcount--; /*Use up the 0xFF chain first*/ + ByteData[index] = compr_char; + } + } + + if (getData) { + g_usDataType |= HEAP_IN; + getData = 0; + } +} + +/* + * + * ispVMShift + * + * Processes the SDR/XSDR/SIR commands. + * + */ + +signed char ispVMShift(signed char a_cCode) +{ + /* 09/11/07 NN added local variables initialization */ + unsigned short iDataIndex = 0; + unsigned short iReadLoop = 0; + signed char cRetCode = 0; + + cRetCode = 0; + /* 09/11/07 NN Type cast mismatch variables */ + g_usiDataSize = (unsigned short) ispVMDataSize(); + + /*clear the flags first*/ + g_usDataType &= ~(SIR_DATA + EXPRESS + SDR_DATA); + switch (a_cCode) { + case SIR: + g_usDataType |= SIR_DATA; + /* + * 1/15/04 If performing cascading, then go directly to SHIFTIR. + * Else, go to IRPAUSE before going to SHIFTIR + */ + if (g_usFlowControl & CASCADE) { + ispVMStateMachine(SHIFTIR); + } else { + ispVMStateMachine(IRPAUSE); + ispVMStateMachine(SHIFTIR); + if (g_usHeadIR > 0) { + ispVMBypass(HIR, g_usHeadIR); + sclock(); + } + } + break; + case XSDR: + g_usDataType |= EXPRESS; /*mark simultaneous in and out*/ + case SDR: + g_usDataType |= SDR_DATA; + /* + * 1/15/04 If already in SHIFTDR, then do not move state or + * shift in header. This would imply that the previously + * shifted frame was a cascaded frame. + */ + if (g_cCurrentJTAGState != SHIFTDR) { + /* + * 1/15/04 If performing cascading, then go directly + * to SHIFTDR. Else, go to DRPAUSE before going + * to SHIFTDR + */ + if (g_usFlowControl & CASCADE) { + if (g_cCurrentJTAGState == DRPAUSE) { + ispVMStateMachine(SHIFTDR); + /* + * 1/15/04 If cascade flag has been seat + * and the current state is DRPAUSE, + * this implies that the first cascaded + * frame is about to be shifted in. The + * header must be shifted prior to + * shifting the first cascaded frame. + */ + if (g_usHeadDR > 0) { + ispVMBypass(HDR, g_usHeadDR); + sclock(); + } + } else { + ispVMStateMachine(SHIFTDR); + } + } else { + ispVMStateMachine(DRPAUSE); + ispVMStateMachine(SHIFTDR); + if (g_usHeadDR > 0) { + ispVMBypass(HDR, g_usHeadDR); + sclock(); + } + } + } + break; + default: + return VME_INVALID_FILE; + } + + cRetCode = ispVMDataCode(); + + if (cRetCode != 0) { + return VME_INVALID_FILE; + } + +#ifdef DEBUG + printf("%d ", g_usiDataSize); + + if (g_usDataType & TDI_DATA) { + puts("TDI "); + PrintData(g_usiDataSize, g_pucInData); + } + + if (g_usDataType & TDO_DATA) { + puts("\n\t\tTDO "); + PrintData(g_usiDataSize, g_pucOutData); + } + + if (g_usDataType & MASK_DATA) { + puts("\n\t\tMASK "); + PrintData(g_usiDataSize, g_pucOutMaskData); + } + + if (g_usDataType & DMASK_DATA) { + puts("\n\t\tDMASK "); + PrintData(g_usiDataSize, g_pucOutDMaskData); + } + + puts(";\n"); +#endif /* DEBUG */ + + if (g_usDataType & TDO_DATA || g_usDataType & DMASK_DATA) { + if (g_usDataType & DMASK_DATA) { + cRetCode = ispVMReadandSave(g_usiDataSize); + if (!cRetCode) { + if (g_usTailDR > 0) { + sclock(); + ispVMBypass(TDR, g_usTailDR); + } + ispVMStateMachine(DRPAUSE); + ispVMStateMachine(SHIFTDR); + if (g_usHeadDR > 0) { + ispVMBypass(HDR, g_usHeadDR); + sclock(); + } + for (iDataIndex = 0; + iDataIndex < g_usiDataSize / 8 + 1; + iDataIndex++) + g_pucInData[iDataIndex] = + g_pucOutData[iDataIndex]; + g_usDataType &= ~(TDO_DATA + DMASK_DATA); + cRetCode = ispVMSend(g_usiDataSize); + } + } else { + cRetCode = ispVMRead(g_usiDataSize); + if (cRetCode == -1 && g_cVendor == XILINX) { + for (iReadLoop = 0; iReadLoop < 30; + iReadLoop++) { + cRetCode = ispVMRead(g_usiDataSize); + if (!cRetCode) { + break; + } else { + /* Always DRPAUSE */ + ispVMStateMachine(DRPAUSE); + /* + * Bypass other devices + * when appropriate + */ + ispVMBypass(TDR, g_usTailDR); + ispVMStateMachine(g_ucEndDR); + ispVMStateMachine(IDLE); + ispVMDelay(1000); + } + } + } + } + } else { /*TDI only*/ + cRetCode = ispVMSend(g_usiDataSize); + } + + /*transfer the input data to the output buffer for the next verify*/ + if ((g_usDataType & EXPRESS) || (a_cCode == SDR)) { + if (g_pucOutData) { + for (iDataIndex = 0; iDataIndex < g_usiDataSize / 8 + 1; + iDataIndex++) + g_pucOutData[iDataIndex] = + g_pucInData[iDataIndex]; + } + } + + switch (a_cCode) { + case SIR: + /* 1/15/04 If not performing cascading, then shift ENDIR */ + if (!(g_usFlowControl & CASCADE)) { + if (g_usTailIR > 0) { + sclock(); + ispVMBypass(TIR, g_usTailIR); + } + ispVMStateMachine(g_ucEndIR); + } + break; + case XSDR: + case SDR: + /* 1/15/04 If not performing cascading, then shift ENDDR */ + if (!(g_usFlowControl & CASCADE)) { + if (g_usTailDR > 0) { + sclock(); + ispVMBypass(TDR, g_usTailDR); + } + ispVMStateMachine(g_ucEndDR); + } + break; + default: + break; + } + + return cRetCode; +} + +/* + * + * ispVMAmble + * + * This routine is to extract Header and Trailer parameter for SIR and + * SDR operations. + * + * The Header and Trailer parameter are the pre-amble and post-amble bit + * stream need to be shifted into TDI or out of TDO of the devices. Mostly + * is for the purpose of bypassing the leading or trailing devices. ispVM + * supports only shifting data into TDI to bypass the devices. + * + * For a single device, the header and trailer parameters are all set to 0 + * as default by ispVM. If it is for multiple devices, the header and trailer + * value will change as specified by the VME file. + * + */ + +signed char ispVMAmble(signed char Code) +{ + signed char compress = 0; + /* 09/11/07 NN Type cast mismatch variables */ + g_usiDataSize = (unsigned short)ispVMDataSize(); + +#ifdef DEBUG + printf("%d", g_usiDataSize); +#endif /* DEBUG */ + + if (g_usiDataSize) { + + /* + * Discard the TDI byte and set the compression bit in the data + * type register to false if compression is set because TDI data + * after HIR/HDR/TIR/TDR is not compressed. + */ + + GetByte(); + if (g_usDataType & COMPRESS) { + g_usDataType &= ~(COMPRESS); + compress = 1; + } + } + + switch (Code) { + case HIR: + + /* + * Store the maximum size of the HIR buffer. + * Used to convert VME to HEX. + */ + + if (g_usiDataSize > g_usHIRSize) { + g_usHIRSize = g_usiDataSize; + } + + /* + * Assign the HIR value and allocate memory. + */ + + g_usHeadIR = g_usiDataSize; + if (g_usHeadIR) { + ispVMMemManager(HIR, g_usHeadIR); + ispVMData(g_pucHIRData); + +#ifdef DEBUG + puts(" TDI "); + PrintData(g_usHeadIR, g_pucHIRData); +#endif /* DEBUG */ + } + break; + case TIR: + + /* + * Store the maximum size of the TIR buffer. + * Used to convert VME to HEX. + */ + + if (g_usiDataSize > g_usTIRSize) { + g_usTIRSize = g_usiDataSize; + } + + /* + * Assign the TIR value and allocate memory. + */ + + g_usTailIR = g_usiDataSize; + if (g_usTailIR) { + ispVMMemManager(TIR, g_usTailIR); + ispVMData(g_pucTIRData); + +#ifdef DEBUG + puts(" TDI "); + PrintData(g_usTailIR, g_pucTIRData); +#endif /* DEBUG */ + } + break; + case HDR: + + /* + * Store the maximum size of the HDR buffer. + * Used to convert VME to HEX. + */ + + if (g_usiDataSize > g_usHDRSize) { + g_usHDRSize = g_usiDataSize; + } + + /* + * Assign the HDR value and allocate memory. + * + */ + + g_usHeadDR = g_usiDataSize; + if (g_usHeadDR) { + ispVMMemManager(HDR, g_usHeadDR); + ispVMData(g_pucHDRData); + +#ifdef DEBUG + puts(" TDI "); + PrintData(g_usHeadDR, g_pucHDRData); +#endif /* DEBUG */ + } + break; + case TDR: + + /* + * Store the maximum size of the TDR buffer. + * Used to convert VME to HEX. + */ + + if (g_usiDataSize > g_usTDRSize) { + g_usTDRSize = g_usiDataSize; + } + + /* + * Assign the TDR value and allocate memory. + * + */ + + g_usTailDR = g_usiDataSize; + if (g_usTailDR) { + ispVMMemManager(TDR, g_usTailDR); + ispVMData(g_pucTDRData); + +#ifdef DEBUG + puts(" TDI "); + PrintData(g_usTailDR, g_pucTDRData); +#endif /* DEBUG */ + } + break; + default: + break; + } + + /* + * + * Re-enable compression if it was previously set. + * + **/ + + if (compress) { + g_usDataType |= COMPRESS; + } + + if (g_usiDataSize) { + Code = GetByte(); + if (Code == CONTINUE) { + return 0; + } else { + + /* + * Encountered invalid opcode. + */ + + return VME_INVALID_FILE; + } + } + + return 0; +} + +/* + * + * ispVMLoop + * + * Perform the function call upon by the REPEAT opcode. + * Memory is to be allocated to store the entire loop from REPEAT to ENDLOOP. + * After the loop is stored then execution begin. The REPEATLOOP flag is set + * on the g_usFlowControl register to indicate the repeat loop is in session + * and therefore fetch opcode from the memory instead of from the file. + * + */ + +signed char ispVMLoop(unsigned short a_usLoopCount) +{ + /* 09/11/07 NN added local variables initialization */ + signed char cRetCode = 0; + unsigned short iHeapIndex = 0; + unsigned short iLoopIndex = 0; + + g_usShiftValue = 0; + for (iHeapIndex = 0; iHeapIndex < g_iHEAPSize; iHeapIndex++) { + g_pucHeapMemory[iHeapIndex] = GetByte(); + } + + if (g_pucHeapMemory[iHeapIndex - 1] != ENDLOOP) { + return VME_INVALID_FILE; + } + + g_usFlowControl |= REPEATLOOP; + g_usDataType |= HEAP_IN; + + for (iLoopIndex = 0; iLoopIndex < a_usLoopCount; iLoopIndex++) { + g_iHeapCounter = 0; + cRetCode = ispVMCode(); + g_usRepeatLoops++; + if (cRetCode < 0) { + break; + } + } + + g_usDataType &= ~(HEAP_IN); + g_usFlowControl &= ~(REPEATLOOP); + return cRetCode; +} + +/* + * + * ispVMBitShift + * + * Shift the TDI stream left or right by the number of bits. The data in + * *g_pucInData is of the VME format, so the actual shifting is the reverse of + * IEEE 1532 or SVF format. + * + */ + +signed char ispVMBitShift(signed char mode, unsigned short bits) +{ + /* 09/11/07 NN added local variables initialization */ + unsigned short i = 0; + unsigned short size = 0; + unsigned short tmpbits = 0; + + if (g_usiDataSize % 8 > 0) { + /* 09/11/07 NN Type cast mismatch variables */ + size = (unsigned short)(g_usiDataSize / 8 + 1); + } else { + /* 09/11/07 NN Type cast mismatch variables */ + size = (unsigned short)(g_usiDataSize / 8); + } + + switch (mode) { + case SHR: + for (i = 0; i < size; i++) { + if (g_pucInData[i] != 0) { + tmpbits = bits; + while (tmpbits > 0) { + g_pucInData[i] <<= 1; + if (g_pucInData[i] == 0) { + i--; + g_pucInData[i] = 1; + } + tmpbits--; + } + } + } + break; + case SHL: + for (i = 0; i < size; i++) { + if (g_pucInData[i] != 0) { + tmpbits = bits; + while (tmpbits > 0) { + g_pucInData[i] >>= 1; + if (g_pucInData[i] == 0) { + i--; + g_pucInData[i] = 8; + } + tmpbits--; + } + } + } + break; + default: + return VME_INVALID_FILE; + } + + return 0; +} + +/* + * + * ispVMComment + * + * Displays the SVF comments. + * + */ + +void ispVMComment(unsigned short a_usCommentSize) +{ + char cCurByte = 0; + for (; a_usCommentSize > 0; a_usCommentSize--) { + /* + * + * Print character to the terminal. + * + **/ + cCurByte = GetByte(); + vme_out_char(cCurByte); + } + cCurByte = '\n'; + vme_out_char(cCurByte); +} + +/* + * + * ispVMHeader + * + * Iterate the length of the header and discard it. + * + */ + +void ispVMHeader(unsigned short a_usHeaderSize) +{ + for (; a_usHeaderSize > 0; a_usHeaderSize--) { + GetByte(); + } +} + +/* + * + * ispVMCalculateCRC32 + * + * Calculate the 32-bit CRC. + * + */ + +void ispVMCalculateCRC32(unsigned char a_ucData) +{ + /* 09/11/07 NN added local variables initialization */ + unsigned char ucIndex = 0; + unsigned char ucFlipData = 0; + unsigned short usCRCTableEntry = 0; + unsigned int crc_table[16] = { + 0x0000, 0xCC01, 0xD801, + 0x1400, 0xF001, 0x3C00, + 0x2800, 0xE401, 0xA001, + 0x6C00, 0x7800, 0xB401, + 0x5000, 0x9C01, 0x8801, + 0x4400 + }; + + for (ucIndex = 0; ucIndex < 8; ucIndex++) { + ucFlipData <<= 1; + if (a_ucData & 0x01) { + ucFlipData |= 0x01; + } + a_ucData >>= 1; + } + + /* 09/11/07 NN Type cast mismatch variables */ + usCRCTableEntry = (unsigned short)(crc_table[g_usCalculatedCRC & 0xF]); + g_usCalculatedCRC = (unsigned short)((g_usCalculatedCRC >> 4) & 0x0FFF); + g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^ + usCRCTableEntry ^ crc_table[ucFlipData & 0xF]); + usCRCTableEntry = (unsigned short)(crc_table[g_usCalculatedCRC & 0xF]); + g_usCalculatedCRC = (unsigned short)((g_usCalculatedCRC >> 4) & 0x0FFF); + g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^ + usCRCTableEntry ^ crc_table[(ucFlipData >> 4) & 0xF]); +} + +/* + * + * ispVMLCOUNT + * + * Process the intelligent programming loops. + * + */ + +signed char ispVMLCOUNT(unsigned short a_usCountSize) +{ + unsigned short usContinue = 1; + unsigned short usIntelBufferIndex = 0; + unsigned short usCountIndex = 0; + signed char cRetCode = 0; + signed char cRepeatHeap = 0; + signed char cOpcode = 0; + unsigned char ucState = 0; + unsigned short usDelay = 0; + unsigned short usToggle = 0; + unsigned char usByte = 0; + + g_usIntelBufferSize = (unsigned short)ispVMDataSize(); + + /* + * Allocate memory for intel buffer. + * + */ + + ispVMMemManager(LHEAP, g_usIntelBufferSize); + + /* + * Store the maximum size of the intelligent buffer. + * Used to convert VME to HEX. + */ + + if (g_usIntelBufferSize > g_usLCOUNTSize) { + g_usLCOUNTSize = g_usIntelBufferSize; + } + + /* + * Copy intel data to the buffer. + */ + + for (usIntelBufferIndex = 0; usIntelBufferIndex < g_usIntelBufferSize; + usIntelBufferIndex++) { + g_pucIntelBuffer[usIntelBufferIndex] = GetByte(); + } + + /* + * Set the data type register to get data from the intelligent + * data buffer. + */ + + g_usDataType |= LHEAP_IN; + + /* + * + * If the HEAP_IN flag is set, temporarily unset the flag so data will be + * retrieved from the status buffer. + * + **/ + + if (g_usDataType & HEAP_IN) { + g_usDataType &= ~HEAP_IN; + cRepeatHeap = 1; + } + +#ifdef DEBUG + printf("LCOUNT %d;\n", a_usCountSize); +#endif /* DEBUG */ + + /* + * Iterate through the intelligent programming command. + */ + + for (usCountIndex = 0; usCountIndex < a_usCountSize; usCountIndex++) { + + /* + * + * Initialize the intel data index to 0 before each iteration. + * + **/ + + g_usIntelDataIndex = 0; + cOpcode = 0; + ucState = 0; + usDelay = 0; + usToggle = 0; + usByte = 0; + usContinue = 1; + + /* + * + * Begin looping through all the VME opcodes. + * + */ + /* + * 4/1/09 Nguyen replaced the recursive function call codes on + * the ispVMLCOUNT function + * + */ + while (usContinue) { + cOpcode = GetByte(); + switch (cOpcode) { + case HIR: + case TIR: + case HDR: + case TDR: + /* + * Set the header/trailer of the device in order + * to bypass successfully. + */ + + ispVMAmble(cOpcode); + break; + case STATE: + + /* + * Step the JTAG state machine. + */ + + ucState = GetByte(); + /* + * Step the JTAG state machine to DRCAPTURE + * to support Looping. + */ + + if ((g_usDataType & LHEAP_IN) && + (ucState == DRPAUSE) && + (g_cCurrentJTAGState == ucState)) { + ispVMStateMachine(DRCAPTURE); + } + ispVMStateMachine(ucState); +#ifdef DEBUG + printf("LDELAY %s ", GetState(ucState)); +#endif /* DEBUG */ + break; + case SIR: +#ifdef DEBUG + printf("SIR "); +#endif /* DEBUG */ + /* + * Shift in data into the device. + */ + + cRetCode = ispVMShift(cOpcode); + break; + case SDR: + +#ifdef DEBUG + printf("LSDR "); +#endif /* DEBUG */ + /* + * Shift in data into the device. + */ + + cRetCode = ispVMShift(cOpcode); + break; + case WAIT: + + /* + * + * Observe delay. + * + */ + + usDelay = (unsigned short)ispVMDataSize(); + ispVMDelay(usDelay); + +#ifdef DEBUG + if (usDelay & 0x8000) { + + /* + * Since MSB is set, the delay time must + * be decoded to millisecond. The + * SVF2VME encodes the MSB to represent + * millisecond. + */ + + usDelay &= ~0x8000; + printf("%.2E SEC;\n", + (float) usDelay / 1000); + } else { + /* + * Since MSB is not set, the delay time + * is given as microseconds. + */ + + printf("%.2E SEC;\n", + (float) usDelay / 1000000); + } +#endif /* DEBUG */ + break; + case TCK: + + /* + * Issue clock toggles. + */ + + usToggle = (unsigned short)ispVMDataSize(); + ispVMClocks(usToggle); + +#ifdef DEBUG + printf("RUNTEST %d TCK;\n", usToggle); +#endif /* DEBUG */ + break; + case ENDLOOP: + + /* + * Exit point from processing loops. + */ + usContinue = 0; + break; + + case COMMENT: + + /* + * Display comment. + */ + + ispVMComment((unsigned short) ispVMDataSize()); + break; + case ispEN: + ucState = GetByte(); + if ((ucState == ON) || (ucState == 0x01)) + writePort(g_ucPinENABLE, 0x01); + else + writePort(g_ucPinENABLE, 0x00); + ispVMDelay(1); + break; + case TRST: + if (GetByte() == 0x01) + writePort(g_ucPinTRST, 0x01); + else + writePort(g_ucPinTRST, 0x00); + ispVMDelay(1); + break; + default: + + /* + * Invalid opcode encountered. + */ + + debug("\nINVALID OPCODE: 0x%.2X\n", cOpcode); + + return VME_INVALID_FILE; + } + } + if (cRetCode >= 0) { + /* + * Break if intelligent programming is successful. + */ + + break; + } + + } + /* + * If HEAP_IN flag was temporarily disabled, + * re-enable it before exiting + */ + + if (cRepeatHeap) { + g_usDataType |= HEAP_IN; + } + + /* + * Set the data type register to not get data from the + * intelligent data buffer. + */ + + g_usDataType &= ~LHEAP_IN; + return cRetCode; +} +/* + * + * ispVMClocks + * + * Applies the specified number of pulses to TCK. + * + */ + +void ispVMClocks(unsigned short Clocks) +{ + unsigned short iClockIndex = 0; + for (iClockIndex = 0; iClockIndex < Clocks; iClockIndex++) { + sclock(); + } +} + +/* + * + * ispVMBypass + * + * This procedure takes care of the HIR, HDR, TIR, TDR for the + * purpose of putting the other devices into Bypass mode. The + * current state is checked to find out if it is at DRPAUSE or + * IRPAUSE. If it is at DRPAUSE, perform bypass register scan. + * If it is at IRPAUSE, scan into instruction registers the bypass + * instruction. + * + */ + +void ispVMBypass(signed char ScanType, unsigned short Bits) +{ + /* 09/11/07 NN added local variables initialization */ + unsigned short iIndex = 0; + unsigned short iSourceIndex = 0; + unsigned char cBitState = 0; + unsigned char cCurByte = 0; + unsigned char *pcSource = NULL; + + if (Bits <= 0) { + return; + } + + switch (ScanType) { + case HIR: + pcSource = g_pucHIRData; + break; + case TIR: + pcSource = g_pucTIRData; + break; + case HDR: + pcSource = g_pucHDRData; + break; + case TDR: + pcSource = g_pucTDRData; + break; + default: + break; + } + + iSourceIndex = 0; + cBitState = 0; + for (iIndex = 0; iIndex < Bits - 1; iIndex++) { + /* Scan instruction or bypass register */ + if (iIndex % 8 == 0) { + cCurByte = pcSource[iSourceIndex++]; + } + cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80) + ? 0x01 : 0x00); + writePort(g_ucPinTDI, cBitState); + sclock(); + } + + if (iIndex % 8 == 0) { + cCurByte = pcSource[iSourceIndex++]; + } + + cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80) + ? 0x01 : 0x00); + writePort(g_ucPinTDI, cBitState); +} + +/* + * + * ispVMStateMachine + * + * This procedure steps all devices in the daisy chain from a given + * JTAG state to the next desirable state. If the next state is TLR, + * the JTAG state machine is brute forced into TLR by driving TMS + * high and pulse TCK 6 times. + * + */ + +void ispVMStateMachine(signed char cNextJTAGState) +{ + /* 09/11/07 NN added local variables initialization */ + signed char cPathIndex = 0; + signed char cStateIndex = 0; + + if ((g_cCurrentJTAGState == cNextJTAGState) && + (cNextJTAGState != RESET)) { + return; + } + + for (cStateIndex = 0; cStateIndex < 25; cStateIndex++) { + if ((g_cCurrentJTAGState == + g_JTAGTransistions[cStateIndex].CurState) && + (cNextJTAGState == + g_JTAGTransistions[cStateIndex].NextState)) { + break; + } + } + + g_cCurrentJTAGState = cNextJTAGState; + for (cPathIndex = 0; + cPathIndex < g_JTAGTransistions[cStateIndex].Pulses; + cPathIndex++) { + if ((g_JTAGTransistions[cStateIndex].Pattern << cPathIndex) + & 0x80) { + writePort(g_ucPinTMS, (unsigned char) 0x01); + } else { + writePort(g_ucPinTMS, (unsigned char) 0x00); + } + sclock(); + } + + writePort(g_ucPinTDI, 0x00); + writePort(g_ucPinTMS, 0x00); +} + +/* + * + * ispVMStart + * + * Enable the port to the device and set the state to RESET (TLR). + * + */ + +void ispVMStart() +{ +#ifdef DEBUG + printf("// ISPVM EMBEDDED ADDED\n"); + printf("STATE RESET;\n"); +#endif + g_usFlowControl = 0; + g_usDataType = g_uiChecksumIndex = g_cCurrentJTAGState = 0; + g_usHeadDR = g_usHeadIR = g_usTailDR = g_usTailIR = 0; + g_usMaxSize = g_usShiftValue = g_usRepeatLoops = 0; + g_usTDOSize = g_usMASKSize = g_usTDISize = 0; + g_usDMASKSize = g_usLCOUNTSize = g_usHDRSize = 0; + g_usTDRSize = g_usHIRSize = g_usTIRSize = g_usHeapSize = 0; + g_pLVDSList = NULL; + g_usLVDSPairCount = 0; + previous_size = 0; + + ispVMStateMachine(RESET); /*step devices to RESET state*/ +} + +/* + * + * ispVMEnd + * + * Set the state of devices to RESET to enable the devices and disable + * the port. + * + */ + +void ispVMEnd() +{ +#ifdef DEBUG + printf("// ISPVM EMBEDDED ADDED\n"); + printf("STATE RESET;\n"); + printf("RUNTEST 1.00E-001 SEC;\n"); +#endif + + ispVMStateMachine(RESET); /*step devices to RESET state */ + ispVMDelay(1000); /*wake up devices*/ +} + +/* + * + * ispVMSend + * + * Send the TDI data stream to devices. The data stream can be + * instructions or data. + * + */ + +signed char ispVMSend(unsigned short a_usiDataSize) +{ + /* 09/11/07 NN added local variables initialization */ + unsigned short iIndex = 0; + unsigned short iInDataIndex = 0; + unsigned char cCurByte = 0; + unsigned char cBitState = 0; + + for (iIndex = 0; iIndex < a_usiDataSize - 1; iIndex++) { + if (iIndex % 8 == 0) { + cCurByte = g_pucInData[iInDataIndex++]; + } + cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80) + ? 0x01 : 0x00); + writePort(g_ucPinTDI, cBitState); + sclock(); + } + + if (iIndex % 8 == 0) { + /* Take care of the last bit */ + cCurByte = g_pucInData[iInDataIndex]; + } + + cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80) + ? 0x01 : 0x00); + + writePort(g_ucPinTDI, cBitState); + if (g_usFlowControl & CASCADE) { + /*1/15/04 Clock in last bit for the first n-1 cascaded frames */ + sclock(); + } + + return 0; +} + +/* + * + * ispVMRead + * + * Read the data stream from devices and verify. + * + */ + +signed char ispVMRead(unsigned short a_usiDataSize) +{ + /* 09/11/07 NN added local variables initialization */ + unsigned short usDataSizeIndex = 0; + unsigned short usErrorCount = 0; + unsigned short usLastBitIndex = 0; + unsigned char cDataByte = 0; + unsigned char cMaskByte = 0; + unsigned char cInDataByte = 0; + unsigned char cCurBit = 0; + unsigned char cByteIndex = 0; + unsigned short usBufferIndex = 0; + unsigned char ucDisplayByte = 0x00; + unsigned char ucDisplayFlag = 0x01; + char StrChecksum[256] = {0}; + unsigned char g_usCalculateChecksum = 0x00; + + /* 09/11/07 NN Type cast mismatch variables */ + usLastBitIndex = (unsigned short)(a_usiDataSize - 1); + +#ifndef DEBUG + /* + * If mask is not all zeros, then set the display flag to 0x00, + * otherwise it shall be set to 0x01 to indicate that data read + * from the device shall be displayed. If DEBUG is defined, + * always display data. + */ + + for (usDataSizeIndex = 0; usDataSizeIndex < (a_usiDataSize + 7) / 8; + usDataSizeIndex++) { + if (g_usDataType & MASK_DATA) { + if (g_pucOutMaskData[usDataSizeIndex] != 0x00) { + ucDisplayFlag = 0x00; + break; + } + } else if (g_usDataType & CMASK_DATA) { + g_usCalculateChecksum = 0x01; + ucDisplayFlag = 0x00; + break; + } else { + ucDisplayFlag = 0x00; + break; + } + } +#endif /* DEBUG */ + + /* + * + * Begin shifting data in and out of the device. + * + **/ + + for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize; + usDataSizeIndex++) { + if (cByteIndex == 0) { + + /* + * Grab byte from TDO buffer. + */ + + if (g_usDataType & TDO_DATA) { + cDataByte = g_pucOutData[usBufferIndex]; + } + + /* + * Grab byte from MASK buffer. + */ + + if (g_usDataType & MASK_DATA) { + cMaskByte = g_pucOutMaskData[usBufferIndex]; + } else { + cMaskByte = 0xFF; + } + + /* + * Grab byte from CMASK buffer. + */ + + if (g_usDataType & CMASK_DATA) { + cMaskByte = 0x00; + g_usCalculateChecksum = 0x01; + } + + /* + * Grab byte from TDI buffer. + */ + + if (g_usDataType & TDI_DATA) { + cInDataByte = g_pucInData[usBufferIndex]; + } + + usBufferIndex++; + } + + cCurBit = readPort(); + + if (ucDisplayFlag) { + ucDisplayByte <<= 1; + ucDisplayByte |= cCurBit; + } + + /* + * Check if data read from port matches with expected TDO. + */ + + if (g_usDataType & TDO_DATA) { + /* 08/28/08 NN Added Calculate checksum support. */ + if (g_usCalculateChecksum) { + if (cCurBit == 0x01) + g_usChecksum += + (1 << (g_uiChecksumIndex % 8)); + g_uiChecksumIndex++; + } else { + if ((((cMaskByte << cByteIndex) & 0x80) + ? 0x01 : 0x00)) { + if (cCurBit != (unsigned char) + (((cDataByte << cByteIndex) & 0x80) + ? 0x01 : 0x00)) { + usErrorCount++; + } + } + } + } + + /* + * Write TDI data to the port. + */ + + writePort(g_ucPinTDI, + (unsigned char)(((cInDataByte << cByteIndex) & 0x80) + ? 0x01 : 0x00)); + + if (usDataSizeIndex < usLastBitIndex) { + + /* + * Clock data out from the data shift register. + */ + + sclock(); + } else if (g_usFlowControl & CASCADE) { + + /* + * Clock in last bit for the first N - 1 cascaded frames + */ + + sclock(); + } + + /* + * Increment the byte index. If it exceeds 7, then reset it back + * to zero. + */ + + cByteIndex++; + if (cByteIndex >= 8) { + if (ucDisplayFlag) { + + /* + * Store displayed data in the TDO buffer. By reusing + * the TDO buffer to store displayed data, there is no + * need to allocate a buffer simply to hold display + * data. This will not cause any false verification + * errors because the true TDO byte has already + * been consumed. + */ + + g_pucOutData[usBufferIndex - 1] = ucDisplayByte; + ucDisplayByte = 0; + } + + cByteIndex = 0; + } + /* 09/12/07 Nguyen changed to display the 1 bit expected data */ + else if (a_usiDataSize == 1) { + if (ucDisplayFlag) { + + /* + * Store displayed data in the TDO buffer. + * By reusing the TDO buffer to store displayed + * data, there is no need to allocate + * a buffer simply to hold display data. This + * will not cause any false verification errors + * because the true TDO byte has already + * been consumed. + */ + + /* + * Flip ucDisplayByte and store it in cDataByte. + */ + cDataByte = 0x00; + for (usBufferIndex = 0; usBufferIndex < 8; + usBufferIndex++) { + cDataByte <<= 1; + if (ucDisplayByte & 0x01) { + cDataByte |= 0x01; + } + ucDisplayByte >>= 1; + } + g_pucOutData[0] = cDataByte; + ucDisplayByte = 0; + } + + cByteIndex = 0; + } + } + + if (ucDisplayFlag) { + +#ifdef DEBUG + debug("RECEIVED TDO ("); +#else + vme_out_string("Display Data: 0x"); +#endif /* DEBUG */ + + /* 09/11/07 NN Type cast mismatch variables */ + for (usDataSizeIndex = (unsigned short) + ((a_usiDataSize + 7) / 8); + usDataSizeIndex > 0 ; usDataSizeIndex--) { + cMaskByte = g_pucOutData[usDataSizeIndex - 1]; + cDataByte = 0x00; + + /* + * Flip cMaskByte and store it in cDataByte. + */ + + for (usBufferIndex = 0; usBufferIndex < 8; + usBufferIndex++) { + cDataByte <<= 1; + if (cMaskByte & 0x01) { + cDataByte |= 0x01; + } + cMaskByte >>= 1; + } +#ifdef DEBUG + printf("%.2X", cDataByte); + if ((((a_usiDataSize + 7) / 8) - usDataSizeIndex) + % 40 == 39) { + printf("\n\t\t"); + } +#else + vme_out_hex(cDataByte); +#endif /* DEBUG */ + } + +#ifdef DEBUG + printf(")\n\n"); +#else + vme_out_string("\n\n"); +#endif /* DEBUG */ + /* 09/02/08 Nguyen changed to display the data Checksum */ + if (g_usChecksum != 0) { + g_usChecksum &= 0xFFFF; + sprintf(StrChecksum, "Data Checksum: %.4lX\n\n", + g_usChecksum); + vme_out_string(StrChecksum); + g_usChecksum = 0; + } + } + + if (usErrorCount > 0) { + if (g_usFlowControl & VERIFYUES) { + vme_out_string( + "USERCODE verification failed. " + "Continue programming......\n\n"); + g_usFlowControl &= ~(VERIFYUES); + return 0; + } else { + +#ifdef DEBUG + printf("TOTAL ERRORS: %d\n", usErrorCount); +#endif /* DEBUG */ + + return VME_VERIFICATION_FAILURE; + } + } else { + if (g_usFlowControl & VERIFYUES) { + vme_out_string("USERCODE verification passed. " + "Programming aborted.\n\n"); + g_usFlowControl &= ~(VERIFYUES); + return 1; + } else { + return 0; + } + } +} + +/* + * + * ispVMReadandSave + * + * Support dynamic I/O. + * + */ + +signed char ispVMReadandSave(unsigned short int a_usiDataSize) +{ + /* 09/11/07 NN added local variables initialization */ + unsigned short int usDataSizeIndex = 0; + unsigned short int usLastBitIndex = 0; + unsigned short int usBufferIndex = 0; + unsigned short int usOutBitIndex = 0; + unsigned short int usLVDSIndex = 0; + unsigned char cDataByte = 0; + unsigned char cDMASKByte = 0; + unsigned char cInDataByte = 0; + unsigned char cCurBit = 0; + unsigned char cByteIndex = 0; + signed char cLVDSByteIndex = 0; + + /* 09/11/07 NN Type cast mismatch variables */ + usLastBitIndex = (unsigned short) (a_usiDataSize - 1); + + /* + * + * Iterate through the data bits. + * + */ + + for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize; + usDataSizeIndex++) { + if (cByteIndex == 0) { + + /* + * Grab byte from DMASK buffer. + */ + + if (g_usDataType & DMASK_DATA) { + cDMASKByte = g_pucOutDMaskData[usBufferIndex]; + } else { + cDMASKByte = 0x00; + } + + /* + * Grab byte from TDI buffer. + */ + + if (g_usDataType & TDI_DATA) { + cInDataByte = g_pucInData[usBufferIndex]; + } + + usBufferIndex++; + } + + cCurBit = readPort(); + cDataByte = (unsigned char)(((cInDataByte << cByteIndex) & 0x80) + ? 0x01 : 0x00); + + /* + * Initialize the byte to be zero. + */ + + if (usOutBitIndex % 8 == 0) { + g_pucOutData[usOutBitIndex / 8] = 0x00; + } + + /* + * Use TDI, DMASK, and device TDO to create new TDI (actually + * stored in g_pucOutData). + */ + + if ((((cDMASKByte << cByteIndex) & 0x80) ? 0x01 : 0x00)) { + + if (g_pLVDSList) { + for (usLVDSIndex = 0; + usLVDSIndex < g_usLVDSPairCount; + usLVDSIndex++) { + if (g_pLVDSList[usLVDSIndex]. + usNegativeIndex == + usDataSizeIndex) { + g_pLVDSList[usLVDSIndex]. + ucUpdate = 0x01; + break; + } + } + } + + /* + * DMASK bit is 1, use TDI. + */ + + g_pucOutData[usOutBitIndex / 8] |= (unsigned char) + (((cDataByte & 0x1) ? 0x01 : 0x00) << + (7 - usOutBitIndex % 8)); + } else { + + /* + * DMASK bit is 0, use device TDO. + */ + + g_pucOutData[usOutBitIndex / 8] |= (unsigned char) + (((cCurBit & 0x1) ? 0x01 : 0x00) << + (7 - usOutBitIndex % 8)); + } + + /* + * Shift in TDI in order to get TDO out. + */ + + usOutBitIndex++; + writePort(g_ucPinTDI, cDataByte); + if (usDataSizeIndex < usLastBitIndex) { + sclock(); + } + + /* + * Increment the byte index. If it exceeds 7, then reset it back + * to zero. + */ + + cByteIndex++; + if (cByteIndex >= 8) { + cByteIndex = 0; + } + } + + /* + * If g_pLVDSList exists and pairs need updating, then update + * the negative-pair to receive the flipped positive-pair value. + */ + + if (g_pLVDSList) { + for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; + usLVDSIndex++) { + if (g_pLVDSList[usLVDSIndex].ucUpdate) { + + /* + * Read the positive value and flip it. + */ + + cDataByte = (unsigned char) + (((g_pucOutData[g_pLVDSList[usLVDSIndex]. + usPositiveIndex / 8] + << (g_pLVDSList[usLVDSIndex]. + usPositiveIndex % 8)) & 0x80) ? + 0x01 : 0x00); + /* 09/11/07 NN Type cast mismatch variables */ + cDataByte = (unsigned char) (!cDataByte); + + /* + * Get the byte that needs modification. + */ + + cInDataByte = + g_pucOutData[g_pLVDSList[usLVDSIndex]. + usNegativeIndex / 8]; + + if (cDataByte) { + + /* + * Copy over the current byte and + * set the negative bit to 1. + */ + + cDataByte = 0x00; + for (cLVDSByteIndex = 7; + cLVDSByteIndex >= 0; + cLVDSByteIndex--) { + cDataByte <<= 1; + if (7 - + (g_pLVDSList[usLVDSIndex]. + usNegativeIndex % 8) == + cLVDSByteIndex) { + + /* + * Set negative bit to 1 + */ + + cDataByte |= 0x01; + } else if (cInDataByte & 0x80) { + cDataByte |= 0x01; + } + + cInDataByte <<= 1; + } + + /* + * Store the modified byte. + */ + + g_pucOutData[g_pLVDSList[usLVDSIndex]. + usNegativeIndex / 8] = cDataByte; + } else { + + /* + * Copy over the current byte and set + * the negative bit to 0. + */ + + cDataByte = 0x00; + for (cLVDSByteIndex = 7; + cLVDSByteIndex >= 0; + cLVDSByteIndex--) { + cDataByte <<= 1; + if (7 - + (g_pLVDSList[usLVDSIndex]. + usNegativeIndex % 8) == + cLVDSByteIndex) { + + /* + * Set negative bit to 0 + */ + + cDataByte |= 0x00; + } else if (cInDataByte & 0x80) { + cDataByte |= 0x01; + } + + cInDataByte <<= 1; + } + + /* + * Store the modified byte. + */ + + g_pucOutData[g_pLVDSList[usLVDSIndex]. + usNegativeIndex / 8] = cDataByte; + } + + break; + } + } + } + + return 0; +} + +signed char ispVMProcessLVDS(unsigned short a_usLVDSCount) +{ + unsigned short usLVDSIndex = 0; + + /* + * Allocate memory to hold LVDS pairs. + */ + + ispVMMemManager(LVDS, a_usLVDSCount); + g_usLVDSPairCount = a_usLVDSCount; + +#ifdef DEBUG + printf("LVDS %d (", a_usLVDSCount); +#endif /* DEBUG */ + + /* + * Iterate through each given LVDS pair. + */ + + for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++) { + + /* + * Assign the positive and negative indices of the LVDS pair. + */ + + /* 09/11/07 NN Type cast mismatch variables */ + g_pLVDSList[usLVDSIndex].usPositiveIndex = + (unsigned short) ispVMDataSize(); + /* 09/11/07 NN Type cast mismatch variables */ + g_pLVDSList[usLVDSIndex].usNegativeIndex = + (unsigned short)ispVMDataSize(); + +#ifdef DEBUG + if (usLVDSIndex < g_usLVDSPairCount - 1) { + printf("%d:%d, ", + g_pLVDSList[usLVDSIndex].usPositiveIndex, + g_pLVDSList[usLVDSIndex].usNegativeIndex); + } else { + printf("%d:%d", + g_pLVDSList[usLVDSIndex].usPositiveIndex, + g_pLVDSList[usLVDSIndex].usNegativeIndex); + } +#endif /* DEBUG */ + + } + +#ifdef DEBUG + printf(");\n", a_usLVDSCount); +#endif /* DEBUG */ + + return 0; +} diff --git a/drivers/fpga/lattice.c b/drivers/fpga/lattice.c new file mode 100644 index 0000000..a0e7823 --- /dev/null +++ b/drivers/fpga/lattice.c @@ -0,0 +1,399 @@ +/* + * (C) Copyright 2010 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de. + * + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * + * ispVM functions adapted from Lattice's ispmVMEmbedded code: + * Copyright 2009 Lattice Semiconductor Corp. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include +#include +#include +#include + +static lattice_board_specific_func *pfns; +static char *fpga_image; +static unsigned long read_bytes; +static unsigned long bufsize; +static unsigned short expectedCRC; + +/* + * External variables and functions declared in ivm_core.c module. + */ +extern unsigned short g_usCalculatedCRC; +extern unsigned short g_usDataType; +extern unsigned char *g_pucIntelBuffer; +extern unsigned char *g_pucHeapMemory; +extern unsigned short g_iHeapCounter; +extern unsigned short g_iHEAPSize; +extern unsigned short g_usIntelDataIndex; +extern unsigned short g_usIntelBufferSize; +extern char *const g_szSupportedVersions[]; + + +/* + * ispVMDelay + * + * Users must implement a delay to observe a_usTimeDelay, where + * bit 15 of the a_usTimeDelay defines the unit. + * 1 = milliseconds + * 0 = microseconds + * Example: + * a_usTimeDelay = 0x0001 = 1 microsecond delay. + * a_usTimeDelay = 0x8001 = 1 millisecond delay. + * + * This subroutine is called upon to provide a delay from 1 millisecond to a few + * hundreds milliseconds each time. + * It is understood that due to a_usTimeDelay is defined as unsigned short, a 16 + * bits integer, this function is restricted to produce a delay to 64000 + * micro-seconds or 32000 milli-second maximum. The VME file will never pass on + * to this function a delay time > those maximum number. If it needs more than + * those maximum, the VME file will launch the delay function several times to + * realize a larger delay time cummulatively. + * It is perfectly alright to provide a longer delay than required. It is not + * acceptable if the delay is shorter. + */ +void ispVMDelay(unsigned short delay) +{ + if (delay & 0x8000) + delay = (delay & ~0x8000) * 1000; + udelay(delay); +} + +void writePort(unsigned char a_ucPins, unsigned char a_ucValue) +{ + a_ucValue = a_ucValue ? 1 : 0; + + switch (a_ucPins) { + case g_ucPinTDI: + pfns->jtag_set_tdi(a_ucValue); + break; + case g_ucPinTCK: + pfns->jtag_set_tck(a_ucValue); + break; + case g_ucPinTMS: + pfns->jtag_set_tms(a_ucValue); + break; + default: + printf("%s: requested unknown pin\n", __func__); + } +} + +unsigned char readPort(void) +{ + return pfns->jtag_get_tdo(); +} + +void sclock(void) +{ + writePort(g_ucPinTCK, 0x01); + writePort(g_ucPinTCK, 0x00); +} + +void calibration(void) +{ + /* Apply 2 pulses to TCK. */ + writePort(g_ucPinTCK, 0x00); + writePort(g_ucPinTCK, 0x01); + writePort(g_ucPinTCK, 0x00); + writePort(g_ucPinTCK, 0x01); + writePort(g_ucPinTCK, 0x00); + + ispVMDelay(0x8001); + + /* Apply 2 pulses to TCK. */ + writePort(g_ucPinTCK, 0x01); + writePort(g_ucPinTCK, 0x00); + writePort(g_ucPinTCK, 0x01); + writePort(g_ucPinTCK, 0x00); +} + +/* + * GetByte + * + * Returns a byte to the caller. The returned byte depends on the + * g_usDataType register. If the HEAP_IN bit is set, then the byte + * is returned from the HEAP. If the LHEAP_IN bit is set, then + * the byte is returned from the intelligent buffer. Otherwise, + * the byte is returned directly from the VME file. + */ +unsigned char GetByte(void) +{ + unsigned char ucData; + unsigned int block_size = 4 * 1024; + + if (g_usDataType & HEAP_IN) { + + /* + * Get data from repeat buffer. + */ + + if (g_iHeapCounter > g_iHEAPSize) { + + /* + * Data over-run. + */ + + return 0xFF; + } + + ucData = g_pucHeapMemory[g_iHeapCounter++]; + } else if (g_usDataType & LHEAP_IN) { + + /* + * Get data from intel buffer. + */ + + if (g_usIntelDataIndex >= g_usIntelBufferSize) { + return 0xFF; + } + + ucData = g_pucIntelBuffer[g_usIntelDataIndex++]; + } else { + if (read_bytes == bufsize) { + return 0xFF; + } + ucData = *fpga_image++; + read_bytes++; + + if (!(read_bytes % block_size)) { + printf("Downloading FPGA %ld/%ld completed\r", + read_bytes, + bufsize); + } + + if (expectedCRC != 0) { + ispVMCalculateCRC32(ucData); + } + } + + return ucData; +} + +signed char ispVM(void) +{ + char szFileVersion[9] = { 0 }; + signed char cRetCode = 0; + signed char cIndex = 0; + signed char cVersionIndex = 0; + unsigned char ucReadByte = 0; + unsigned short crc; + + g_pucHeapMemory = NULL; + g_iHeapCounter = 0; + g_iHEAPSize = 0; + g_usIntelDataIndex = 0; + g_usIntelBufferSize = 0; + g_usCalculatedCRC = 0; + expectedCRC = 0; + ucReadByte = GetByte(); + switch (ucReadByte) { + case FILE_CRC: + crc = (unsigned char)GetByte(); + crc <<= 8; + crc |= GetByte(); + expectedCRC = crc; + + for (cIndex = 0; cIndex < 8; cIndex++) + szFileVersion[cIndex] = GetByte(); + + break; + default: + szFileVersion[0] = (signed char) ucReadByte; + for (cIndex = 1; cIndex < 8; cIndex++) + szFileVersion[cIndex] = GetByte(); + + break; + } + + /* + * + * Compare the VME file version against the supported version. + * + */ + + for (cVersionIndex = 0; g_szSupportedVersions[cVersionIndex] != 0; + cVersionIndex++) { + for (cIndex = 0; cIndex < 8; cIndex++) { + if (szFileVersion[cIndex] != + g_szSupportedVersions[cVersionIndex][cIndex]) { + cRetCode = VME_VERSION_FAILURE; + break; + } + cRetCode = 0; + } + + if (cRetCode == 0) { + break; + } + } + + if (cRetCode < 0) { + return VME_VERSION_FAILURE; + } + + printf("VME file checked: starting downloading to FPGA\n"); + + ispVMStart(); + + cRetCode = ispVMCode(); + + ispVMEnd(); + ispVMFreeMem(); + puts("\n"); + + if (cRetCode == 0 && expectedCRC != 0 && + (expectedCRC != g_usCalculatedCRC)) { + printf("Expected CRC: 0x%.4X\n", expectedCRC); + printf("Calculated CRC: 0x%.4X\n", g_usCalculatedCRC); + return VME_CRC_FAILURE; + } + return cRetCode; +} + +static int lattice_validate(Lattice_desc *desc, const char *fn) +{ + int ret_val = FALSE; + + if (desc) { + if ((desc->family > min_lattice_type) && + (desc->family < max_lattice_type)) { + if ((desc->iface > min_lattice_iface_type) && + (desc->iface < max_lattice_iface_type)) { + if (desc->size) { + ret_val = TRUE; + } else { + printf("%s: NULL part size\n", fn); + } + } else { + printf("%s: Invalid Interface type, %d\n", + fn, desc->iface); + } + } else { + printf("%s: Invalid family type, %d\n", + fn, desc->family); + } + } else { + printf("%s: NULL descriptor!\n", fn); + } + + return ret_val; +} + +int lattice_load(Lattice_desc *desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + if (!lattice_validate(desc, (char *)__func__)) { + printf("%s: Invalid device descriptor\n", __func__); + } else { + pfns = desc->iface_fns; + + switch (desc->family) { + case Lattice_XP2: + fpga_image = buf; + read_bytes = 0; + bufsize = bsize; + debug("%s: Launching the Lattice ISPVME Loader:" + " addr 0x%x size 0x%x...\n", + __func__, fpga_image, bufsize); + ret_val = ispVM(); + if (ret_val) + printf("%s: error %d downloading FPGA image\n", + __func__, ret_val); + else + puts("FPGA downloaded successfully\n"); + break; + default: + printf("%s: Unsupported family type, %d\n", + __func__, desc->family); + } + } + + return ret_val; +} + +int lattice_dump(Lattice_desc *desc, void *buf, size_t bsize) +{ + puts("Dump not supported for Lattice FPGA\n"); + + return FPGA_FAIL; + +} + +int lattice_info(Lattice_desc *desc) +{ + int ret_val = FPGA_FAIL; + + if (lattice_validate(desc, (char *)__func__)) { + printf("Family: \t"); + switch (desc->family) { + case Lattice_XP2: + puts("XP2\n"); + break; + /* Add new family types here */ + default: + printf("Unknown family type, %d\n", desc->family); + } + + puts("Interface type:\t"); + switch (desc->iface) { + case lattice_jtag_mode: + puts("JTAG Mode\n"); + break; + /* Add new interface types here */ + default: + printf("Unsupported interface type, %d\n", desc->iface); + } + + printf("Device Size: \t%d bytes\n", + desc->size); + + if (desc->iface_fns) { + printf("Device Function Table @ 0x%p\n", + desc->iface_fns); + switch (desc->family) { + case Lattice_XP2: + break; + /* Add new family types here */ + default: + break; + } + } else { + puts("No Device Function Table.\n"); + } + + if (desc->desc) + printf("Model: \t%s\n", desc->desc); + + ret_val = FPGA_SUCCESS; + } else { + printf("%s: Invalid device descriptor\n", __func__); + } + + return ret_val; +} + + diff --git a/include/fpga.h b/include/fpga.h index 84d7b9f..ac24f2b 100644 --- a/include/fpga.h +++ b/include/fpga.h @@ -61,6 +61,7 @@ typedef enum { /* typedef fpga_type */ fpga_min_type, /* range check value */ fpga_xilinx, /* Xilinx Family) */ fpga_altera, /* unimplemented */ + fpga_lattice, /* Lattice family */ fpga_undefined /* invalid range check value */ } fpga_type; /* end, typedef fpga_type */ diff --git a/include/lattice.h b/include/lattice.h new file mode 100755 index 0000000..33d2ac3 --- /dev/null +++ b/include/lattice.h @@ -0,0 +1,319 @@ +/* + * Porting to U-Boot: + * + * (C) Copyright 2010 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de. + * + * Lattice's ispVME Embedded Tool to load Lattice's FPGA: + * + * Lattice Semiconductor Corp. Copyright 2009 + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _VME_OPCODE_H +#define _VME_OPCODE_H + +#define VME_VERSION_NUMBER "12.1" + +/* Maximum declarations. */ + +#define VMEHEXMAX 60000L /* The hex file is split 60K per file. */ +#define SCANMAX 64000L /* The maximum SDR/SIR burst. */ + +/* + * + * Supported JTAG state transitions. + * + */ + +#define RESET 0x00 +#define IDLE 0x01 +#define IRPAUSE 0x02 +#define DRPAUSE 0x03 +#define SHIFTIR 0x04 +#define SHIFTDR 0x05 +/* 11/15/05 Nguyen changed to support DRCAPTURE*/ +#define DRCAPTURE 0x06 + +/* + * Flow control register bit definitions. A set bit indicates + * that the register currently exhibits the corresponding mode. + */ + +#define INTEL_PRGM 0x0001 /* Intelligent programming is in effect. */ +#define CASCADE 0x0002 /* Currently splitting large SDR. */ +#define REPEATLOOP 0x0008 /* Currently executing a repeat loop. */ +#define SHIFTRIGHT 0x0080 /* The next data stream needs a right shift. */ +#define SHIFTLEFT 0x0100 /* The next data stream needs a left shift. */ +#define VERIFYUES 0x0200 /* Continue if fail is in effect. */ + +/* + * DataType register bit definitions. A set bit indicates + * that the register currently holds the corresponding type of data. + */ + +#define EXPRESS 0x0001 /* Simultaneous program and verify. */ +#define SIR_DATA 0x0002 /* SIR is the active SVF command. */ +#define SDR_DATA 0x0004 /* SDR is the active SVF command. */ +#define COMPRESS 0x0008 /* Data is compressed. */ +#define TDI_DATA 0x0010 /* TDI data is present. */ +#define TDO_DATA 0x0020 /* TDO data is present. */ +#define MASK_DATA 0x0040 /* MASK data is present. */ +#define HEAP_IN 0x0080 /* Data is from the heap. */ +#define LHEAP_IN 0x0200 /* Data is from intel data buffer. */ +#define VARIABLE 0x0400 /* Data is from a declared variable. */ +#define CRC_DATA 0x0800 /* CRC data is pressent. */ +#define CMASK_DATA 0x1000 /* CMASK data is pressent. */ +#define RMASK_DATA 0x2000 /* RMASK data is pressent. */ +#define READ_DATA 0x4000 /* READ data is pressent. */ +#define DMASK_DATA 0x8000 /* DMASK data is pressent. */ + +/* + * + * Pin opcodes. + * + */ + +#define signalENABLE 0x1C /* ispENABLE pin. */ +#define signalTMS 0x1D /* TMS pin. */ +#define signalTCK 0x1E /* TCK pin. */ +#define signalTDI 0x1F /* TDI pin. */ +#define signalTRST 0x20 /* TRST pin. */ + +/* + * + * Supported vendors. + * + */ + +#define VENDOR 0x56 +#define LATTICE 0x01 +#define ALTERA 0x02 +#define XILINX 0x03 + +/* + * Opcode definitions. + * + * Note: opcodes must be unique. + */ + +#define ENDDATA 0x00 /* The end of the current SDR data stream. */ +#define RUNTEST 0x01 /* The duration to stay at the stable state. */ +#define ENDDR 0x02 /* The stable state after SDR. */ +#define ENDIR 0x03 /* The stable state after SIR. */ +#define ENDSTATE 0x04 /* The stable state after RUNTEST. */ +#define TRST 0x05 /* Assert the TRST pin. */ +#define HIR 0x06 /* + * The sum of the IR bits of the + * leading devices. + */ +#define TIR 0x07 /* + * The sum of the IR bits of the trailing + * devices. + */ +#define HDR 0x08 /* The number of leading devices. */ +#define TDR 0x09 /* The number of trailing devices. */ +#define ispEN 0x0A /* Assert the ispEN pin. */ +#define FREQUENCY 0x0B /* + * The maximum clock rate to run the JTAG state + * machine. + */ +#define STATE 0x10 /* Move to the next stable state. */ +#define SIR 0x11 /* The instruction stream follows. */ +#define SDR 0x12 /* The data stream follows. */ +#define TDI 0x13 /* The following data stream feeds into + the device. */ +#define TDO 0x14 /* + * The following data stream is compared against + * the device. + */ +#define MASK 0x15 /* The following data stream is used as mask. */ +#define XSDR 0x16 /* + * The following data stream is for simultaneous + * program and verify. + */ +#define XTDI 0x17 /* The following data stream is for shift in + * only. It must be stored for the next + * XSDR. + */ +#define XTDO 0x18 /* + * There is not data stream. The data stream + * was stored from the previous XTDI. + */ +#define MEM 0x19 /* + * The maximum memory needed to allocate in + * order hold one row of data. + */ +#define WAIT 0x1A /* The duration of delay to observe. */ +#define TCK 0x1B /* The number of TCK pulses. */ +#define SHR 0x23 /* + * Set the flow control register for + * right shift + */ +#define SHL 0x24 /* + * Set the flow control register for left shift. + */ +#define HEAP 0x32 /* The memory size needed to hold one loop. */ +#define REPEAT 0x33 /* The beginning of the loop. */ +#define LEFTPAREN 0x35 /* The beginning of data following the loop. */ +#define VAR 0x55 /* Plac holder for loop data. */ +#define SEC 0x1C /* + * The delay time in seconds that must be + * observed. + */ +#define SMASK 0x1D /* The mask for TDI data. */ +#define MAX_WAIT 0x1E /* The absolute maximum wait time. */ +#define ON 0x1F /* Assert the targeted pin. */ +#define OFF 0x20 /* Dis-assert the targeted pin. */ +#define SETFLOW 0x30 /* Change the flow control register. */ +#define RESETFLOW 0x31 /* Clear the flow control register. */ + +#define CRC 0x47 /* + * The following data stream is used for CRC + * calculation. + */ +#define CMASK 0x48 /* + * The following data stream is used as mask + * for CRC calculation. + */ +#define RMASK 0x49 /* + * The following data stream is used as mask + * for read and save. + */ +#define READ 0x50 /* + * The following data stream is used for read + * and save. + */ +#define ENDLOOP 0x59 /* The end of the repeat loop. */ +#define SECUREHEAP 0x60 /* Used to secure the HEAP opcode. */ +#define VUES 0x61 /* Support continue if fail. */ +#define DMASK 0x62 /* + * The following data stream is used for dynamic + * I/O. + */ +#define COMMENT 0x63 /* Support SVF comments in the VME file. */ +#define HEADER 0x64 /* Support header in VME file. */ +#define FILE_CRC 0x65 /* Support crc-protected VME file. */ +#define LCOUNT 0x66 /* Support intelligent programming. */ +#define LDELAY 0x67 /* Support intelligent programming. */ +#define LSDR 0x68 /* Support intelligent programming. */ +#define LHEAP 0x69 /* + * Memory needed to hold intelligent data + * buffer + */ +#define CONTINUE 0x70 /* Allow continuation. */ +#define LVDS 0x71 /* Support LVDS. */ +#define ENDVME 0x7F /* End of the VME file. */ +#define ENDFILE 0xFF /* End of file. */ + +/* + * + * ispVM Embedded Return Codes. + * + */ + +#define VME_VERIFICATION_FAILURE -1 +#define VME_FILE_READ_FAILURE -2 +#define VME_VERSION_FAILURE -3 +#define VME_INVALID_FILE -4 +#define VME_ARGUMENT_FAILURE -5 +#define VME_CRC_FAILURE -6 + +#define g_ucPinTDI 0x01 +#define g_ucPinTCK 0x02 +#define g_ucPinTMS 0x04 +#define g_ucPinENABLE 0x08 +#define g_ucPinTRST 0x10 + +/* + * + * Type definitions. + * + */ + +/* Support LVDS */ +typedef struct { + unsigned short usPositiveIndex; + unsigned short usNegativeIndex; + unsigned char ucUpdate; +} LVDSPair; + +typedef enum { + min_lattice_iface_type, /* insert all new types after this */ + lattice_jtag_mode, /* jtag/tap */ + max_lattice_iface_type /* insert all new types before this */ +} Lattice_iface; + +typedef enum { + min_lattice_type, + Lattice_XP2, /* Lattice XP2 Family */ + max_lattice_type /* insert all new types before this */ +} Lattice_Family; + +typedef struct { + Lattice_Family family; /* part type */ + Lattice_iface iface; /* interface type */ + size_t size; /* bytes of data part can accept */ + void *iface_fns; /* interface function table */ + void *base; /* base interface address */ + int cookie; /* implementation specific cookie */ + char *desc; /* description string */ +} Lattice_desc; /* end, typedef Altera_desc */ + +/* Lattice Model Type */ +#define CONFIG_SYS_XP2 CONFIG_SYS_FPGA_DEV(0x1) + +/* Board specific implementation specific function types */ +typedef void (*Lattice_jtag_init)(void); +typedef void (*Lattice_jtag_set_tdi)(int v); +typedef void (*Lattice_jtag_set_tms)(int v); +typedef void (*Lattice_jtag_set_tck)(int v); +typedef int (*Lattice_jtag_get_tdo)(void); + +typedef struct { + Lattice_jtag_init jtag_init; + Lattice_jtag_set_tdi jtag_set_tdi; + Lattice_jtag_set_tms jtag_set_tms; + Lattice_jtag_set_tck jtag_set_tck; + Lattice_jtag_get_tdo jtag_get_tdo; +} lattice_board_specific_func; + +void writePort(unsigned char pins, unsigned char value); +unsigned char readPort(void); +void sclock(void); +void ispVMDelay(unsigned short int a_usMicroSecondDelay); +void calibration(void); + +int lattice_load(Lattice_desc *desc, void *buf, size_t bsize); +int lattice_dump(Lattice_desc *desc, void *buf, size_t bsize); +int lattice_info(Lattice_desc *desc); + +void ispVMStart(void); +void ispVMEnd(void); +signed char ispVMCode(void); +void ispVMDelay(unsigned short int a_usMicroSecondDelay); +void ispVMCalculateCRC32(unsigned char a_ucData); +unsigned char GetByte(void); +void writePort(unsigned char pins, unsigned char value); +unsigned char readPort(void); +void sclock(void); +#endif + -- cgit v0.10.2 From 70e23264ffd18270741197be4d59691499c0ba5c Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Fri, 1 Oct 2010 12:34:34 +0200 Subject: MX31: Adding missing iomux pin to MX.31 registers Signed-off-by: Stefano Babic diff --git a/arch/arm/include/asm/arch-mx31/mx31-regs.h b/arch/arm/include/asm/arch-mx31/mx31-regs.h index f05e743..7a98d1c 100644 --- a/arch/arm/include/asm/arch-mx31/mx31-regs.h +++ b/arch/arm/include/asm/arch-mx31/mx31-regs.h @@ -214,6 +214,10 @@ struct gpio_regs { #define MUX_CTL_CSPI1_MISO 0x8d #define MUX_CTL_CSPI1_SS0 0x8e #define MUX_CTL_CSPI1_SS1 0x8f +#define MUX_CTL_STXD6 0x90 +#define MUX_CTL_SRXD6 0x91 +#define MUX_CTL_SCK6 0x92 +#define MUX_CTL_SFS6 0x93 #define MUX_CTL_NFC_WP 0xD0 #define MUX_CTL_NFC_CE 0xD1 @@ -224,6 +228,9 @@ struct gpio_regs { #define MUX_CTL_NFC_CLE 0xD7 +#define MUX_CTL_CAPTURE 0x150 +#define MUX_CTL_COMPARE 0x151 + /* * Helper macros for the MUX_[contact name]__[pin function] macros */ -- cgit v0.10.2 From b9eb3fdf2f545626525b85953d322b2f8d67d319 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Tue, 29 Jun 2010 11:48:24 +0200 Subject: MX31: Add support to update FPGA bitstream The patch adds the possibility to update the QONG FPGA (a Lattice XP2-5E) with u-boot using some GPIOs to drive the JTAG interface. Signed-off-by: Stefano Babic diff --git a/board/davedenx/qong/Makefile b/board/davedenx/qong/Makefile index 93e1985..ada6e03 100644 --- a/board/davedenx/qong/Makefile +++ b/board/davedenx/qong/Makefile @@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(BOARD).a -COBJS := qong.o +COBJS := qong.o fpga.o SOBJS := lowlevel_init.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/board/davedenx/qong/fpga.c b/board/davedenx/qong/fpga.c new file mode 100644 index 0000000..f865eb4 --- /dev/null +++ b/board/davedenx/qong/fpga.c @@ -0,0 +1,95 @@ +/* + * (C) Copyright 2010 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include "qong_fpga.h" + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_FPGA) + +static void qong_jtag_init(void) +{ + return; +} + +static void qong_fpga_jtag_set_tdi(int value) +{ + mxc_gpio_set(QONG_FPGA_TDI_PIN, value); +} + +static void qong_fpga_jtag_set_tms(int value) +{ + mxc_gpio_set(QONG_FPGA_TMS_PIN, value); +} + +static void qong_fpga_jtag_set_tck(int value) +{ + mxc_gpio_set(QONG_FPGA_TCK_PIN, value); +} + +static int qong_fpga_jtag_get_tdo(void) +{ + return mxc_gpio_get(QONG_FPGA_TDO_PIN); +} + +lattice_board_specific_func qong_fpga_fns = { + qong_jtag_init, + qong_fpga_jtag_set_tdi, + qong_fpga_jtag_set_tms, + qong_fpga_jtag_set_tck, + qong_fpga_jtag_get_tdo +}; + +Lattice_desc qong_fpga[CONFIG_FPGA_COUNT] = { + { + Lattice_XP2, + lattice_jtag_mode, + 356519, + (void *) &qong_fpga_fns, + NULL, + 0, + "lfxp2_5e_ftbga256" + }, +}; + +int qong_fpga_init(void) +{ + int i; + + fpga_init(); + + for (i = 0; i < CONFIG_FPGA_COUNT; i++) { + fpga_add(fpga_lattice, &qong_fpga[i]); + } + return 0; +} + +#endif + diff --git a/board/davedenx/qong/qong.c b/board/davedenx/qong/qong.c index 9abc29c..efeb0bb 100644 --- a/board/davedenx/qong/qong.c +++ b/board/davedenx/qong/qong.c @@ -73,6 +73,15 @@ int board_early_init_f (void) /* set interrupt pin as input */ mxc_gpio_direction(QONG_FPGA_IRQ_PIN, MXC_GPIO_DIRECTION_IN); + /* FPGA JTAG Interface */ + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_SFS6, MUX_CTL_GPIO)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_SCK6, MUX_CTL_GPIO)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_CAPTURE, MUX_CTL_GPIO)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_COMPARE, MUX_CTL_GPIO)); + mxc_gpio_direction(QONG_FPGA_TCK_PIN, MXC_GPIO_DIRECTION_OUT); + mxc_gpio_direction(QONG_FPGA_TMS_PIN, MXC_GPIO_DIRECTION_OUT); + mxc_gpio_direction(QONG_FPGA_TDI_PIN, MXC_GPIO_DIRECTION_OUT); + mxc_gpio_direction(QONG_FPGA_TDO_PIN, MXC_GPIO_DIRECTION_IN); #endif /* setup pins for UART1 */ @@ -146,6 +155,8 @@ int board_init (void) gd->bd->bi_arch_number = MACH_TYPE_QONG; gd->bd->bi_boot_params = (0x80000100); /* adress of boot parameters */ + qong_fpga_init(); + return 0; } diff --git a/board/davedenx/qong/qong_fpga.h b/board/davedenx/qong/qong_fpga.h index 4e11f5a..4e79ac2 100644 --- a/board/davedenx/qong/qong_fpga.h +++ b/board/davedenx/qong/qong_fpga.h @@ -24,7 +24,6 @@ #ifndef QONG_FPGA_H #define QONG_FPGA_H -#ifdef CONFIG_QONG_FPGA #define QONG_FPGA_CTRL_BASE CONFIG_FPGA_BASE #define QONG_FPGA_CTRL_VERSION (QONG_FPGA_CTRL_BASE + 0x00000000) #define QONG_FPGA_PERIPH_SIZE (1 << 24) @@ -35,6 +34,6 @@ #define QONG_FPGA_TDO_PIN 7 #define QONG_FPGA_RST_PIN 48 #define QONG_FPGA_IRQ_PIN 40 -#endif +int qong_fpga_init(void); #endif /* QONG_FPGA_H */ diff --git a/include/configs/qong.h b/include/configs/qong.h index cbb53dd..0465ff4 100644 --- a/include/configs/qong.h +++ b/include/configs/qong.h @@ -66,8 +66,11 @@ #define CONFIG_FSL_PMIC_MODE (SPI_MODE_0 | SPI_CS_HIGH) /* FPGA */ +#define CONFIG_FPGA #define CONFIG_QONG_FPGA 1 #define CONFIG_FPGA_BASE (CS1_BASE) +#define CONFIG_FPGA_LATTICE +#define CONFIG_FPGA_COUNT 1 #ifdef CONFIG_QONG_FPGA /* Ethernet */ -- cgit v0.10.2 From f76888c29427c2fbb0a7df700cd50c558b49b108 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Wed, 6 Oct 2010 08:59:26 +0200 Subject: MX31: add support for setting pin pads The patch adds a utility function and defines to set the pad as it is done in linux. Signed-off-by: Stefano Babic diff --git a/arch/arm/cpu/arm1136/mx31/generic.c b/arch/arm/cpu/arm1136/mx31/generic.c index 1415d6c..cbe8243 100644 --- a/arch/arm/cpu/arm1136/mx31/generic.c +++ b/arch/arm/cpu/arm1136/mx31/generic.c @@ -23,6 +23,7 @@ #include #include +#include static u32 mx31_decode_pll(u32 reg, u32 infreq) { @@ -90,6 +91,22 @@ void mx31_gpio_mux(unsigned long mode) __REG(reg) = tmp; } +void mx31_set_pad(enum iomux_pins pin, u32 config) +{ + u32 field, l; + void *reg; + + pin &= IOMUX_PADNUM_MASK; + reg = (IOMUXC_BASE + 0x154) + (pin + 2) / 3 * 4; + field = (pin + 2) % 3; + + l = __raw_readl(reg); + l &= ~(0x1ff << (field * 10)); + l |= config << (field * 10); + __raw_writel(l, reg); + +} + #if defined(CONFIG_DISPLAY_CPUINFO) int print_cpuinfo (void) { diff --git a/arch/arm/include/asm/arch-mx31/mx31-regs.h b/arch/arm/include/asm/arch-mx31/mx31-regs.h index 7a98d1c..46ed47c 100644 --- a/arch/arm/include/asm/arch-mx31/mx31-regs.h +++ b/arch/arm/include/asm/arch-mx31/mx31-regs.h @@ -64,6 +64,370 @@ struct gpio_regs { u32 gpio_psr; }; +#define IOMUX_PADNUM_MASK 0x1ff +#define IOMUX_PIN(gpionum, padnum) ((padnum) & IOMUX_PADNUM_MASK) + +/* + * various IOMUX pad functions + */ +enum iomux_pad_config { + PAD_CTL_NOLOOPBACK = 0x0 << 9, + PAD_CTL_LOOPBACK = 0x1 << 9, + PAD_CTL_PKE_NONE = 0x0 << 8, + PAD_CTL_PKE_ENABLE = 0x1 << 8, + PAD_CTL_PUE_KEEPER = 0x0 << 7, + PAD_CTL_PUE_PUD = 0x1 << 7, + PAD_CTL_100K_PD = 0x0 << 5, + PAD_CTL_100K_PU = 0x1 << 5, + PAD_CTL_47K_PU = 0x2 << 5, + PAD_CTL_22K_PU = 0x3 << 5, + PAD_CTL_HYS_CMOS = 0x0 << 4, + PAD_CTL_HYS_SCHMITZ = 0x1 << 4, + PAD_CTL_ODE_CMOS = 0x0 << 3, + PAD_CTL_ODE_OpenDrain = 0x1 << 3, + PAD_CTL_DRV_NORMAL = 0x0 << 1, + PAD_CTL_DRV_HIGH = 0x1 << 1, + PAD_CTL_DRV_MAX = 0x2 << 1, + PAD_CTL_SRE_SLOW = 0x0 << 0, + PAD_CTL_SRE_FAST = 0x1 << 0 +}; + +/* + * This enumeration is constructed based on the Section + * "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated + * value is constructed based on the rules described above. + */ + +enum iomux_pins { + MX31_PIN_TTM_PAD = IOMUX_PIN(0xff, 0), + MX31_PIN_CSPI3_SPI_RDY = IOMUX_PIN(0xff, 1), + MX31_PIN_CSPI3_SCLK = IOMUX_PIN(0xff, 2), + MX31_PIN_CSPI3_MISO = IOMUX_PIN(0xff, 3), + MX31_PIN_CSPI3_MOSI = IOMUX_PIN(0xff, 4), + MX31_PIN_CLKSS = IOMUX_PIN(0xff, 5), + MX31_PIN_CE_CONTROL = IOMUX_PIN(0xff, 6), + MX31_PIN_ATA_RESET_B = IOMUX_PIN(95, 7), + MX31_PIN_ATA_DMACK = IOMUX_PIN(94, 8), + MX31_PIN_ATA_DIOW = IOMUX_PIN(93, 9), + MX31_PIN_ATA_DIOR = IOMUX_PIN(92, 10), + MX31_PIN_ATA_CS1 = IOMUX_PIN(91, 11), + MX31_PIN_ATA_CS0 = IOMUX_PIN(90, 12), + MX31_PIN_SD1_DATA3 = IOMUX_PIN(63, 13), + MX31_PIN_SD1_DATA2 = IOMUX_PIN(62, 14), + MX31_PIN_SD1_DATA1 = IOMUX_PIN(61, 15), + MX31_PIN_SD1_DATA0 = IOMUX_PIN(60, 16), + MX31_PIN_SD1_CLK = IOMUX_PIN(59, 17), + MX31_PIN_SD1_CMD = IOMUX_PIN(58, 18), + MX31_PIN_D3_SPL = IOMUX_PIN(0xff, 19), + MX31_PIN_D3_CLS = IOMUX_PIN(0xff, 20), + MX31_PIN_D3_REV = IOMUX_PIN(0xff, 21), + MX31_PIN_CONTRAST = IOMUX_PIN(0xff, 22), + MX31_PIN_VSYNC3 = IOMUX_PIN(0xff, 23), + MX31_PIN_READ = IOMUX_PIN(0xff, 24), + MX31_PIN_WRITE = IOMUX_PIN(0xff, 25), + MX31_PIN_PAR_RS = IOMUX_PIN(0xff, 26), + MX31_PIN_SER_RS = IOMUX_PIN(89, 27), + MX31_PIN_LCS1 = IOMUX_PIN(88, 28), + MX31_PIN_LCS0 = IOMUX_PIN(87, 29), + MX31_PIN_SD_D_CLK = IOMUX_PIN(86, 30), + MX31_PIN_SD_D_IO = IOMUX_PIN(85, 31), + MX31_PIN_SD_D_I = IOMUX_PIN(84, 32), + MX31_PIN_DRDY0 = IOMUX_PIN(0xff, 33), + MX31_PIN_FPSHIFT = IOMUX_PIN(0xff, 34), + MX31_PIN_HSYNC = IOMUX_PIN(0xff, 35), + MX31_PIN_VSYNC0 = IOMUX_PIN(0xff, 36), + MX31_PIN_LD17 = IOMUX_PIN(0xff, 37), + MX31_PIN_LD16 = IOMUX_PIN(0xff, 38), + MX31_PIN_LD15 = IOMUX_PIN(0xff, 39), + MX31_PIN_LD14 = IOMUX_PIN(0xff, 40), + MX31_PIN_LD13 = IOMUX_PIN(0xff, 41), + MX31_PIN_LD12 = IOMUX_PIN(0xff, 42), + MX31_PIN_LD11 = IOMUX_PIN(0xff, 43), + MX31_PIN_LD10 = IOMUX_PIN(0xff, 44), + MX31_PIN_LD9 = IOMUX_PIN(0xff, 45), + MX31_PIN_LD8 = IOMUX_PIN(0xff, 46), + MX31_PIN_LD7 = IOMUX_PIN(0xff, 47), + MX31_PIN_LD6 = IOMUX_PIN(0xff, 48), + MX31_PIN_LD5 = IOMUX_PIN(0xff, 49), + MX31_PIN_LD4 = IOMUX_PIN(0xff, 50), + MX31_PIN_LD3 = IOMUX_PIN(0xff, 51), + MX31_PIN_LD2 = IOMUX_PIN(0xff, 52), + MX31_PIN_LD1 = IOMUX_PIN(0xff, 53), + MX31_PIN_LD0 = IOMUX_PIN(0xff, 54), + MX31_PIN_USBH2_DATA1 = IOMUX_PIN(0xff, 55), + MX31_PIN_USBH2_DATA0 = IOMUX_PIN(0xff, 56), + MX31_PIN_USBH2_NXT = IOMUX_PIN(0xff, 57), + MX31_PIN_USBH2_STP = IOMUX_PIN(0xff, 58), + MX31_PIN_USBH2_DIR = IOMUX_PIN(0xff, 59), + MX31_PIN_USBH2_CLK = IOMUX_PIN(0xff, 60), + MX31_PIN_USBOTG_DATA7 = IOMUX_PIN(0xff, 61), + MX31_PIN_USBOTG_DATA6 = IOMUX_PIN(0xff, 62), + MX31_PIN_USBOTG_DATA5 = IOMUX_PIN(0xff, 63), + MX31_PIN_USBOTG_DATA4 = IOMUX_PIN(0xff, 64), + MX31_PIN_USBOTG_DATA3 = IOMUX_PIN(0xff, 65), + MX31_PIN_USBOTG_DATA2 = IOMUX_PIN(0xff, 66), + MX31_PIN_USBOTG_DATA1 = IOMUX_PIN(0xff, 67), + MX31_PIN_USBOTG_DATA0 = IOMUX_PIN(0xff, 68), + MX31_PIN_USBOTG_NXT = IOMUX_PIN(0xff, 69), + MX31_PIN_USBOTG_STP = IOMUX_PIN(0xff, 70), + MX31_PIN_USBOTG_DIR = IOMUX_PIN(0xff, 71), + MX31_PIN_USBOTG_CLK = IOMUX_PIN(0xff, 72), + MX31_PIN_USB_BYP = IOMUX_PIN(31, 73), + MX31_PIN_USB_OC = IOMUX_PIN(30, 74), + MX31_PIN_USB_PWR = IOMUX_PIN(29, 75), + MX31_PIN_SJC_MOD = IOMUX_PIN(0xff, 76), + MX31_PIN_DE_B = IOMUX_PIN(0xff, 77), + MX31_PIN_TRSTB = IOMUX_PIN(0xff, 78), + MX31_PIN_TDO = IOMUX_PIN(0xff, 79), + MX31_PIN_TDI = IOMUX_PIN(0xff, 80), + MX31_PIN_TMS = IOMUX_PIN(0xff, 81), + MX31_PIN_TCK = IOMUX_PIN(0xff, 82), + MX31_PIN_RTCK = IOMUX_PIN(0xff, 83), + MX31_PIN_KEY_COL7 = IOMUX_PIN(57, 84), + MX31_PIN_KEY_COL6 = IOMUX_PIN(56, 85), + MX31_PIN_KEY_COL5 = IOMUX_PIN(55, 86), + MX31_PIN_KEY_COL4 = IOMUX_PIN(54, 87), + MX31_PIN_KEY_COL3 = IOMUX_PIN(0xff, 88), + MX31_PIN_KEY_COL2 = IOMUX_PIN(0xff, 89), + MX31_PIN_KEY_COL1 = IOMUX_PIN(0xff, 90), + MX31_PIN_KEY_COL0 = IOMUX_PIN(0xff, 91), + MX31_PIN_KEY_ROW7 = IOMUX_PIN(53, 92), + MX31_PIN_KEY_ROW6 = IOMUX_PIN(52, 93), + MX31_PIN_KEY_ROW5 = IOMUX_PIN(51, 94), + MX31_PIN_KEY_ROW4 = IOMUX_PIN(50, 95), + MX31_PIN_KEY_ROW3 = IOMUX_PIN(0xff, 96), + MX31_PIN_KEY_ROW2 = IOMUX_PIN(0xff, 97), + MX31_PIN_KEY_ROW1 = IOMUX_PIN(0xff, 98), + MX31_PIN_KEY_ROW0 = IOMUX_PIN(0xff, 99), + MX31_PIN_BATT_LINE = IOMUX_PIN(49, 100), + MX31_PIN_CTS2 = IOMUX_PIN(0xff, 101), + MX31_PIN_RTS2 = IOMUX_PIN(0xff, 102), + MX31_PIN_TXD2 = IOMUX_PIN(28, 103), + MX31_PIN_RXD2 = IOMUX_PIN(27, 104), + MX31_PIN_DTR_DCE2 = IOMUX_PIN(48, 105), + MX31_PIN_DCD_DTE1 = IOMUX_PIN(47, 106), + MX31_PIN_RI_DTE1 = IOMUX_PIN(46, 107), + MX31_PIN_DSR_DTE1 = IOMUX_PIN(45, 108), + MX31_PIN_DTR_DTE1 = IOMUX_PIN(44, 109), + MX31_PIN_DCD_DCE1 = IOMUX_PIN(43, 110), + MX31_PIN_RI_DCE1 = IOMUX_PIN(42, 111), + MX31_PIN_DSR_DCE1 = IOMUX_PIN(41, 112), + MX31_PIN_DTR_DCE1 = IOMUX_PIN(40, 113), + MX31_PIN_CTS1 = IOMUX_PIN(39, 114), + MX31_PIN_RTS1 = IOMUX_PIN(38, 115), + MX31_PIN_TXD1 = IOMUX_PIN(37, 116), + MX31_PIN_RXD1 = IOMUX_PIN(36, 117), + MX31_PIN_CSPI2_SPI_RDY = IOMUX_PIN(0xff, 118), + MX31_PIN_CSPI2_SCLK = IOMUX_PIN(0xff, 119), + MX31_PIN_CSPI2_SS2 = IOMUX_PIN(0xff, 120), + MX31_PIN_CSPI2_SS1 = IOMUX_PIN(0xff, 121), + MX31_PIN_CSPI2_SS0 = IOMUX_PIN(0xff, 122), + MX31_PIN_CSPI2_MISO = IOMUX_PIN(0xff, 123), + MX31_PIN_CSPI2_MOSI = IOMUX_PIN(0xff, 124), + MX31_PIN_CSPI1_SPI_RDY = IOMUX_PIN(0xff, 125), + MX31_PIN_CSPI1_SCLK = IOMUX_PIN(0xff, 126), + MX31_PIN_CSPI1_SS2 = IOMUX_PIN(0xff, 127), + MX31_PIN_CSPI1_SS1 = IOMUX_PIN(0xff, 128), + MX31_PIN_CSPI1_SS0 = IOMUX_PIN(0xff, 129), + MX31_PIN_CSPI1_MISO = IOMUX_PIN(0xff, 130), + MX31_PIN_CSPI1_MOSI = IOMUX_PIN(0xff, 131), + MX31_PIN_SFS6 = IOMUX_PIN(26, 132), + MX31_PIN_SCK6 = IOMUX_PIN(25, 133), + MX31_PIN_SRXD6 = IOMUX_PIN(24, 134), + MX31_PIN_STXD6 = IOMUX_PIN(23, 135), + MX31_PIN_SFS5 = IOMUX_PIN(0xff, 136), + MX31_PIN_SCK5 = IOMUX_PIN(0xff, 137), + MX31_PIN_SRXD5 = IOMUX_PIN(22, 138), + MX31_PIN_STXD5 = IOMUX_PIN(21, 139), + MX31_PIN_SFS4 = IOMUX_PIN(0xff, 140), + MX31_PIN_SCK4 = IOMUX_PIN(0xff, 141), + MX31_PIN_SRXD4 = IOMUX_PIN(20, 142), + MX31_PIN_STXD4 = IOMUX_PIN(19, 143), + MX31_PIN_SFS3 = IOMUX_PIN(0xff, 144), + MX31_PIN_SCK3 = IOMUX_PIN(0xff, 145), + MX31_PIN_SRXD3 = IOMUX_PIN(18, 146), + MX31_PIN_STXD3 = IOMUX_PIN(17, 147), + MX31_PIN_I2C_DAT = IOMUX_PIN(0xff, 148), + MX31_PIN_I2C_CLK = IOMUX_PIN(0xff, 149), + MX31_PIN_CSI_PIXCLK = IOMUX_PIN(83, 150), + MX31_PIN_CSI_HSYNC = IOMUX_PIN(82, 151), + MX31_PIN_CSI_VSYNC = IOMUX_PIN(81, 152), + MX31_PIN_CSI_MCLK = IOMUX_PIN(80, 153), + MX31_PIN_CSI_D15 = IOMUX_PIN(79, 154), + MX31_PIN_CSI_D14 = IOMUX_PIN(78, 155), + MX31_PIN_CSI_D13 = IOMUX_PIN(77, 156), + MX31_PIN_CSI_D12 = IOMUX_PIN(76, 157), + MX31_PIN_CSI_D11 = IOMUX_PIN(75, 158), + MX31_PIN_CSI_D10 = IOMUX_PIN(74, 159), + MX31_PIN_CSI_D9 = IOMUX_PIN(73, 160), + MX31_PIN_CSI_D8 = IOMUX_PIN(72, 161), + MX31_PIN_CSI_D7 = IOMUX_PIN(71, 162), + MX31_PIN_CSI_D6 = IOMUX_PIN(70, 163), + MX31_PIN_CSI_D5 = IOMUX_PIN(69, 164), + MX31_PIN_CSI_D4 = IOMUX_PIN(68, 165), + MX31_PIN_M_GRANT = IOMUX_PIN(0xff, 166), + MX31_PIN_M_REQUEST = IOMUX_PIN(0xff, 167), + MX31_PIN_PC_POE = IOMUX_PIN(0xff, 168), + MX31_PIN_PC_RW_B = IOMUX_PIN(0xff, 169), + MX31_PIN_IOIS16 = IOMUX_PIN(0xff, 170), + MX31_PIN_PC_RST = IOMUX_PIN(0xff, 171), + MX31_PIN_PC_BVD2 = IOMUX_PIN(0xff, 172), + MX31_PIN_PC_BVD1 = IOMUX_PIN(0xff, 173), + MX31_PIN_PC_VS2 = IOMUX_PIN(0xff, 174), + MX31_PIN_PC_VS1 = IOMUX_PIN(0xff, 175), + MX31_PIN_PC_PWRON = IOMUX_PIN(0xff, 176), + MX31_PIN_PC_READY = IOMUX_PIN(0xff, 177), + MX31_PIN_PC_WAIT_B = IOMUX_PIN(0xff, 178), + MX31_PIN_PC_CD2_B = IOMUX_PIN(0xff, 179), + MX31_PIN_PC_CD1_B = IOMUX_PIN(0xff, 180), + MX31_PIN_D0 = IOMUX_PIN(0xff, 181), + MX31_PIN_D1 = IOMUX_PIN(0xff, 182), + MX31_PIN_D2 = IOMUX_PIN(0xff, 183), + MX31_PIN_D3 = IOMUX_PIN(0xff, 184), + MX31_PIN_D4 = IOMUX_PIN(0xff, 185), + MX31_PIN_D5 = IOMUX_PIN(0xff, 186), + MX31_PIN_D6 = IOMUX_PIN(0xff, 187), + MX31_PIN_D7 = IOMUX_PIN(0xff, 188), + MX31_PIN_D8 = IOMUX_PIN(0xff, 189), + MX31_PIN_D9 = IOMUX_PIN(0xff, 190), + MX31_PIN_D10 = IOMUX_PIN(0xff, 191), + MX31_PIN_D11 = IOMUX_PIN(0xff, 192), + MX31_PIN_D12 = IOMUX_PIN(0xff, 193), + MX31_PIN_D13 = IOMUX_PIN(0xff, 194), + MX31_PIN_D14 = IOMUX_PIN(0xff, 195), + MX31_PIN_D15 = IOMUX_PIN(0xff, 196), + MX31_PIN_NFRB = IOMUX_PIN(16, 197), + MX31_PIN_NFCE_B = IOMUX_PIN(15, 198), + MX31_PIN_NFWP_B = IOMUX_PIN(14, 199), + MX31_PIN_NFCLE = IOMUX_PIN(13, 200), + MX31_PIN_NFALE = IOMUX_PIN(12, 201), + MX31_PIN_NFRE_B = IOMUX_PIN(11, 202), + MX31_PIN_NFWE_B = IOMUX_PIN(10, 203), + MX31_PIN_SDQS3 = IOMUX_PIN(0xff, 204), + MX31_PIN_SDQS2 = IOMUX_PIN(0xff, 205), + MX31_PIN_SDQS1 = IOMUX_PIN(0xff, 206), + MX31_PIN_SDQS0 = IOMUX_PIN(0xff, 207), + MX31_PIN_SDCLK_B = IOMUX_PIN(0xff, 208), + MX31_PIN_SDCLK = IOMUX_PIN(0xff, 209), + MX31_PIN_SDCKE1 = IOMUX_PIN(0xff, 210), + MX31_PIN_SDCKE0 = IOMUX_PIN(0xff, 211), + MX31_PIN_SDWE = IOMUX_PIN(0xff, 212), + MX31_PIN_CAS = IOMUX_PIN(0xff, 213), + MX31_PIN_RAS = IOMUX_PIN(0xff, 214), + MX31_PIN_RW = IOMUX_PIN(0xff, 215), + MX31_PIN_BCLK = IOMUX_PIN(0xff, 216), + MX31_PIN_LBA = IOMUX_PIN(0xff, 217), + MX31_PIN_ECB = IOMUX_PIN(0xff, 218), + MX31_PIN_CS5 = IOMUX_PIN(0xff, 219), + MX31_PIN_CS4 = IOMUX_PIN(0xff, 220), + MX31_PIN_CS3 = IOMUX_PIN(0xff, 221), + MX31_PIN_CS2 = IOMUX_PIN(0xff, 222), + MX31_PIN_CS1 = IOMUX_PIN(0xff, 223), + MX31_PIN_CS0 = IOMUX_PIN(0xff, 224), + MX31_PIN_OE = IOMUX_PIN(0xff, 225), + MX31_PIN_EB1 = IOMUX_PIN(0xff, 226), + MX31_PIN_EB0 = IOMUX_PIN(0xff, 227), + MX31_PIN_DQM3 = IOMUX_PIN(0xff, 228), + MX31_PIN_DQM2 = IOMUX_PIN(0xff, 229), + MX31_PIN_DQM1 = IOMUX_PIN(0xff, 230), + MX31_PIN_DQM0 = IOMUX_PIN(0xff, 231), + MX31_PIN_SD31 = IOMUX_PIN(0xff, 232), + MX31_PIN_SD30 = IOMUX_PIN(0xff, 233), + MX31_PIN_SD29 = IOMUX_PIN(0xff, 234), + MX31_PIN_SD28 = IOMUX_PIN(0xff, 235), + MX31_PIN_SD27 = IOMUX_PIN(0xff, 236), + MX31_PIN_SD26 = IOMUX_PIN(0xff, 237), + MX31_PIN_SD25 = IOMUX_PIN(0xff, 238), + MX31_PIN_SD24 = IOMUX_PIN(0xff, 239), + MX31_PIN_SD23 = IOMUX_PIN(0xff, 240), + MX31_PIN_SD22 = IOMUX_PIN(0xff, 241), + MX31_PIN_SD21 = IOMUX_PIN(0xff, 242), + MX31_PIN_SD20 = IOMUX_PIN(0xff, 243), + MX31_PIN_SD19 = IOMUX_PIN(0xff, 244), + MX31_PIN_SD18 = IOMUX_PIN(0xff, 245), + MX31_PIN_SD17 = IOMUX_PIN(0xff, 246), + MX31_PIN_SD16 = IOMUX_PIN(0xff, 247), + MX31_PIN_SD15 = IOMUX_PIN(0xff, 248), + MX31_PIN_SD14 = IOMUX_PIN(0xff, 249), + MX31_PIN_SD13 = IOMUX_PIN(0xff, 250), + MX31_PIN_SD12 = IOMUX_PIN(0xff, 251), + MX31_PIN_SD11 = IOMUX_PIN(0xff, 252), + MX31_PIN_SD10 = IOMUX_PIN(0xff, 253), + MX31_PIN_SD9 = IOMUX_PIN(0xff, 254), + MX31_PIN_SD8 = IOMUX_PIN(0xff, 255), + MX31_PIN_SD7 = IOMUX_PIN(0xff, 256), + MX31_PIN_SD6 = IOMUX_PIN(0xff, 257), + MX31_PIN_SD5 = IOMUX_PIN(0xff, 258), + MX31_PIN_SD4 = IOMUX_PIN(0xff, 259), + MX31_PIN_SD3 = IOMUX_PIN(0xff, 260), + MX31_PIN_SD2 = IOMUX_PIN(0xff, 261), + MX31_PIN_SD1 = IOMUX_PIN(0xff, 262), + MX31_PIN_SD0 = IOMUX_PIN(0xff, 263), + MX31_PIN_SDBA0 = IOMUX_PIN(0xff, 264), + MX31_PIN_SDBA1 = IOMUX_PIN(0xff, 265), + MX31_PIN_A25 = IOMUX_PIN(0xff, 266), + MX31_PIN_A24 = IOMUX_PIN(0xff, 267), + MX31_PIN_A23 = IOMUX_PIN(0xff, 268), + MX31_PIN_A22 = IOMUX_PIN(0xff, 269), + MX31_PIN_A21 = IOMUX_PIN(0xff, 270), + MX31_PIN_A20 = IOMUX_PIN(0xff, 271), + MX31_PIN_A19 = IOMUX_PIN(0xff, 272), + MX31_PIN_A18 = IOMUX_PIN(0xff, 273), + MX31_PIN_A17 = IOMUX_PIN(0xff, 274), + MX31_PIN_A16 = IOMUX_PIN(0xff, 275), + MX31_PIN_A14 = IOMUX_PIN(0xff, 276), + MX31_PIN_A15 = IOMUX_PIN(0xff, 277), + MX31_PIN_A13 = IOMUX_PIN(0xff, 278), + MX31_PIN_A12 = IOMUX_PIN(0xff, 279), + MX31_PIN_A11 = IOMUX_PIN(0xff, 280), + MX31_PIN_MA10 = IOMUX_PIN(0xff, 281), + MX31_PIN_A10 = IOMUX_PIN(0xff, 282), + MX31_PIN_A9 = IOMUX_PIN(0xff, 283), + MX31_PIN_A8 = IOMUX_PIN(0xff, 284), + MX31_PIN_A7 = IOMUX_PIN(0xff, 285), + MX31_PIN_A6 = IOMUX_PIN(0xff, 286), + MX31_PIN_A5 = IOMUX_PIN(0xff, 287), + MX31_PIN_A4 = IOMUX_PIN(0xff, 288), + MX31_PIN_A3 = IOMUX_PIN(0xff, 289), + MX31_PIN_A2 = IOMUX_PIN(0xff, 290), + MX31_PIN_A1 = IOMUX_PIN(0xff, 291), + MX31_PIN_A0 = IOMUX_PIN(0xff, 292), + MX31_PIN_VPG1 = IOMUX_PIN(0xff, 293), + MX31_PIN_VPG0 = IOMUX_PIN(0xff, 294), + MX31_PIN_DVFS1 = IOMUX_PIN(0xff, 295), + MX31_PIN_DVFS0 = IOMUX_PIN(0xff, 296), + MX31_PIN_VSTBY = IOMUX_PIN(0xff, 297), + MX31_PIN_POWER_FAIL = IOMUX_PIN(0xff, 298), + MX31_PIN_CKIL = IOMUX_PIN(0xff, 299), + MX31_PIN_BOOT_MODE4 = IOMUX_PIN(0xff, 300), + MX31_PIN_BOOT_MODE3 = IOMUX_PIN(0xff, 301), + MX31_PIN_BOOT_MODE2 = IOMUX_PIN(0xff, 302), + MX31_PIN_BOOT_MODE1 = IOMUX_PIN(0xff, 303), + MX31_PIN_BOOT_MODE0 = IOMUX_PIN(0xff, 304), + MX31_PIN_CLKO = IOMUX_PIN(0xff, 305), + MX31_PIN_POR_B = IOMUX_PIN(0xff, 306), + MX31_PIN_RESET_IN_B = IOMUX_PIN(0xff, 307), + MX31_PIN_CKIH = IOMUX_PIN(0xff, 308), + MX31_PIN_SIMPD0 = IOMUX_PIN(35, 309), + MX31_PIN_SRX0 = IOMUX_PIN(34, 310), + MX31_PIN_STX0 = IOMUX_PIN(33, 311), + MX31_PIN_SVEN0 = IOMUX_PIN(32, 312), + MX31_PIN_SRST0 = IOMUX_PIN(67, 313), + MX31_PIN_SCLK0 = IOMUX_PIN(66, 314), + MX31_PIN_GPIO3_1 = IOMUX_PIN(65, 315), + MX31_PIN_GPIO3_0 = IOMUX_PIN(64, 316), + MX31_PIN_GPIO1_6 = IOMUX_PIN(6, 317), + MX31_PIN_GPIO1_5 = IOMUX_PIN(5, 318), + MX31_PIN_GPIO1_4 = IOMUX_PIN(4, 319), + MX31_PIN_GPIO1_3 = IOMUX_PIN(3, 320), + MX31_PIN_GPIO1_2 = IOMUX_PIN(2, 321), + MX31_PIN_GPIO1_1 = IOMUX_PIN(1, 322), + MX31_PIN_GPIO1_0 = IOMUX_PIN(0, 323), + MX31_PIN_PWMO = IOMUX_PIN(9, 324), + MX31_PIN_WATCHDOG_RST = IOMUX_PIN(0xff, 325), + MX31_PIN_COMPARE = IOMUX_PIN(8, 326), + MX31_PIN_CAPTURE = IOMUX_PIN(7, 327), +}; /* Bit definitions for RCSR register in CCM */ #define CCM_RCSR_NF16B (1 << 31) @@ -194,6 +558,12 @@ struct gpio_regs { /* Register offsets based on IOMUXC_BASE */ /* 0x00 .. 0x7b */ +#define MUX_CTL_USBH2_DATA1 0x40 +#define MUX_CTL_USBH2_DIR 0x44 +#define MUX_CTL_USBH2_STP 0x45 +#define MUX_CTL_USBH2_NXT 0x46 +#define MUX_CTL_USBH2_DATA0 0x47 +#define MUX_CTL_USBH2_CLK 0x4B #define MUX_CTL_RTS1 0x7c #define MUX_CTL_CTS1 0x7d #define MUX_CTL_DTR_DCE1 0x7e @@ -219,6 +589,11 @@ struct gpio_regs { #define MUX_CTL_SCK6 0x92 #define MUX_CTL_SFS6 0x93 +#define MUX_CTL_STXD3 0x9C +#define MUX_CTL_SRXD3 0x9D +#define MUX_CTL_SCK3 0x9E +#define MUX_CTL_SFS3 0x9F + #define MUX_CTL_NFC_WP 0xD0 #define MUX_CTL_NFC_CE 0xD1 #define MUX_CTL_NFC_RB 0xD2 @@ -324,4 +699,33 @@ struct gpio_regs { #define IRAM_BASE_ADDR 0x1FFFC000 #define IRAM_SIZE (16 * 1024) +#define MX31_AIPS1_BASE_ADDR 0x43f00000 +#define MX31_OTG_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x88000) + +/* USB portsc */ +/* values for portsc field */ +#define MXC_EHCI_PHY_LOW_POWER_SUSPEND (1 << 23) +#define MXC_EHCI_FORCE_FS (1 << 24) +#define MXC_EHCI_UTMI_8BIT (0 << 28) +#define MXC_EHCI_UTMI_16BIT (1 << 28) +#define MXC_EHCI_SERIAL (1 << 29) +#define MXC_EHCI_MODE_UTMI (0 << 30) +#define MXC_EHCI_MODE_PHILIPS (1 << 30) +#define MXC_EHCI_MODE_ULPI (2 << 30) +#define MXC_EHCI_MODE_SERIAL (3 << 30) + +/* values for flags field */ +#define MXC_EHCI_INTERFACE_DIFF_UNI (0 << 0) +#define MXC_EHCI_INTERFACE_DIFF_BI (1 << 0) +#define MXC_EHCI_INTERFACE_SINGLE_UNI (2 << 0) +#define MXC_EHCI_INTERFACE_SINGLE_BI (3 << 0) +#define MXC_EHCI_INTERFACE_MASK (0xf) + +#define MXC_EHCI_POWER_PINS_ENABLED (1 << 5) +#define MXC_EHCI_TTL_ENABLED (1 << 6) + +#define MXC_EHCI_INTERNAL_PHY (1 << 7) +#define MXC_EHCI_IPPUE_DOWN (1 << 8) +#define MXC_EHCI_IPPUE_UP (1 << 9) + #endif /* __ASM_ARCH_MX31_REGS_H */ diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 7f04b49..51831f0 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c @@ -334,37 +334,6 @@ enum ipu_panel { #define IOMUX_MODE_L(pin, mode) IOMUX_MODE(((pin) + 0xc) ^ 3, mode) -enum lcd_pin { - MX31_PIN_D3_SPL = IOMUX_PIN(0xff, 19), - MX31_PIN_D3_CLS = IOMUX_PIN(0xff, 20), - MX31_PIN_D3_REV = IOMUX_PIN(0xff, 21), - MX31_PIN_CONTRAST = IOMUX_PIN(0xff, 22), - MX31_PIN_VSYNC3 = IOMUX_PIN(0xff, 23), - - MX31_PIN_DRDY0 = IOMUX_PIN(0xff, 33), - MX31_PIN_FPSHIFT = IOMUX_PIN(0xff, 34), - MX31_PIN_HSYNC = IOMUX_PIN(0xff, 35), - - MX31_PIN_LD17 = IOMUX_PIN(0xff, 37), - MX31_PIN_LD16 = IOMUX_PIN(0xff, 38), - MX31_PIN_LD15 = IOMUX_PIN(0xff, 39), - MX31_PIN_LD14 = IOMUX_PIN(0xff, 40), - MX31_PIN_LD13 = IOMUX_PIN(0xff, 41), - MX31_PIN_LD12 = IOMUX_PIN(0xff, 42), - MX31_PIN_LD11 = IOMUX_PIN(0xff, 43), - MX31_PIN_LD10 = IOMUX_PIN(0xff, 44), - MX31_PIN_LD9 = IOMUX_PIN(0xff, 45), - MX31_PIN_LD8 = IOMUX_PIN(0xff, 46), - MX31_PIN_LD7 = IOMUX_PIN(0xff, 47), - MX31_PIN_LD6 = IOMUX_PIN(0xff, 48), - MX31_PIN_LD5 = IOMUX_PIN(0xff, 49), - MX31_PIN_LD4 = IOMUX_PIN(0xff, 50), - MX31_PIN_LD3 = IOMUX_PIN(0xff, 51), - MX31_PIN_LD2 = IOMUX_PIN(0xff, 52), - MX31_PIN_LD1 = IOMUX_PIN(0xff, 53), - MX31_PIN_LD0 = IOMUX_PIN(0xff, 54), -}; - struct chan_param_mem_planar { /* Word 0 */ u32 xv:10; -- cgit v0.10.2 From 5b591502f9fc340df8fb1e3bec918009ba3bc313 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Wed, 6 Oct 2010 09:00:01 +0200 Subject: MX31: Add support for MXC EHCI controller The patch adds the EHCI controller for the i.MX31 Soc. Signed-off-by: Stefano Babic diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 255679a..399520e 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -36,6 +36,7 @@ COBJS-$(CONFIG_USB_SL811HS) += sl811-hcd.o # echi COBJS-$(CONFIG_USB_EHCI) += ehci-hcd.o COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o +COBJS-$(CONFIG_USB_EHCI_MXC) += ehci-mxc.o COBJS-$(CONFIG_USB_EHCI_PPC4XX) += ehci-ppc4xx.o COBJS-$(CONFIG_USB_EHCI_IXP4XX) += ehci-ixp.o COBJS-$(CONFIG_USB_EHCI_KIRKWOOD) += ehci-kirkwood.o diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c new file mode 100644 index 0000000..af8ee90 --- /dev/null +++ b/drivers/usb/host/ehci-mxc.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2009 Daniel Mack + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include +#include +#include +#include +#include +#include + +#include "ehci.h" +#include "ehci-core.h" + +#define USBCTRL_OTGBASE_OFFSET 0x600 + +#define MX31_OTG_SIC_SHIFT 29 +#define MX31_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT) +#define MX31_OTG_PM_BIT (1 << 24) + +#define MX31_H2_SIC_SHIFT 21 +#define MX31_H2_SIC_MASK (0x3 << MX31_H2_SIC_SHIFT) +#define MX31_H2_PM_BIT (1 << 16) +#define MX31_H2_DT_BIT (1 << 5) + +#define MX31_H1_SIC_SHIFT 13 +#define MX31_H1_SIC_MASK (0x3 << MX31_H1_SIC_SHIFT) +#define MX31_H1_PM_BIT (1 << 8) +#define MX31_H1_DT_BIT (1 << 4) + +static int mxc_set_usbcontrol(int port, unsigned int flags) +{ + unsigned int v; +#ifdef CONFIG_MX31 + v = readl(MX31_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET); + + switch (port) { + case 0: /* OTG port */ + v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); + v |= (flags & MXC_EHCI_INTERFACE_MASK) + << MX31_OTG_SIC_SHIFT; + if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) + v |= MX31_OTG_PM_BIT; + + break; + case 1: /* H1 port */ + v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | + MX31_H1_DT_BIT); + v |= (flags & MXC_EHCI_INTERFACE_MASK) + << MX31_H1_SIC_SHIFT; + if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) + v |= MX31_H1_PM_BIT; + + if (!(flags & MXC_EHCI_TTL_ENABLED)) + v |= MX31_H1_DT_BIT; + + break; + case 2: /* H2 port */ + v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | + MX31_H2_DT_BIT); + v |= (flags & MXC_EHCI_INTERFACE_MASK) + << MX31_H2_SIC_SHIFT; + if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) + v |= MX31_H2_PM_BIT; + + if (!(flags & MXC_EHCI_TTL_ENABLED)) + v |= MX31_H2_DT_BIT; + + break; + default: + return -EINVAL; + } + + writel(v, MX31_OTG_BASE_ADDR + + USBCTRL_OTGBASE_OFFSET); +#endif + return 0; +} + +int ehci_hcd_init(void) +{ + u32 tmp; + struct usb_ehci *ehci; + struct clock_control_regs *sc_regs = + (struct clock_control_regs *)CCM_BASE; + + tmp = __raw_readl(&sc_regs->ccmr); + __raw_writel(__raw_readl(&sc_regs->ccmr) | (1 << 9), &sc_regs->ccmr) ; + + udelay(80); + + /* Take USB2 */ + ehci = (struct usb_ehci *)(MX31_OTG_BASE_ADDR + + (0x200 * CONFIG_MXC_USB_PORT)); + hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); + hcor = (struct ehci_hcor *)((uint32_t) hccr + + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); + setbits_le32(&ehci->usbmode, CM_HOST); + setbits_le32(&ehci->control, USB_EN); + + __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc); + + mxc_set_usbcontrol(CONFIG_MXC_USB_PORT, CONFIG_MXC_USB_FLAGS); + + return 0; +} + +/* + * Destroy the appropriate control structures corresponding + * the the EHCI host controller. + */ +int ehci_hcd_stop(void) +{ + return 0; +} -- cgit v0.10.2 From d7dc464be4ee246ecab6c7934b322b5aaecfe5f6 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Tue, 5 Oct 2010 14:05:11 +0200 Subject: MX31: Add USB Host support to the QONG board Signed-off-by: Stefano Babic diff --git a/board/davedenx/qong/qong.c b/board/davedenx/qong/qong.c index efeb0bb..8a81cfc 100644 --- a/board/davedenx/qong/qong.c +++ b/board/davedenx/qong/qong.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -97,6 +98,38 @@ int board_early_init_f (void) mx31_gpio_mux(MUX_CSPI2_SCLK__CSPI2_CLK); mx31_gpio_mux(MUX_CSPI2_SPI_RDY__CSPI2_DATAREADY_B); + /* Setup pins for USB2 Host */ + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_USBH2_CLK, MUX_CTL_FUNC)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_USBH2_DIR, MUX_CTL_FUNC)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_USBH2_NXT, MUX_CTL_FUNC)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_USBH2_STP, MUX_CTL_FUNC)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_USBH2_DATA0, MUX_CTL_FUNC)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_USBH2_DATA1, MUX_CTL_FUNC)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_STXD3, MUX_CTL_FUNC)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_SRXD3, MUX_CTL_FUNC)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_SCK3, MUX_CTL_FUNC)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_SFS3, MUX_CTL_FUNC)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_STXD6, MUX_CTL_FUNC)); + mx31_gpio_mux(IOMUX_MODE(MUX_CTL_SRXD6, MUX_CTL_FUNC)); + +#define H2_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ + PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) + + mx31_set_pad(MX31_PIN_USBH2_CLK, H2_PAD_CFG); + mx31_set_pad(MX31_PIN_USBH2_DIR, H2_PAD_CFG); + mx31_set_pad(MX31_PIN_USBH2_NXT, H2_PAD_CFG); + mx31_set_pad(MX31_PIN_USBH2_STP, H2_PAD_CFG); + mx31_set_pad(MX31_PIN_USBH2_DATA0, H2_PAD_CFG); /* USBH2_DATA0 */ + mx31_set_pad(MX31_PIN_USBH2_DATA1, H2_PAD_CFG); /* USBH2_DATA1 */ + mx31_set_pad(MX31_PIN_SRXD6, H2_PAD_CFG); /* USBH2_DATA2 */ + mx31_set_pad(MX31_PIN_STXD6, H2_PAD_CFG); /* USBH2_DATA3 */ + mx31_set_pad(MX31_PIN_SFS3, H2_PAD_CFG); /* USBH2_DATA4 */ + mx31_set_pad(MX31_PIN_SCK3, H2_PAD_CFG); /* USBH2_DATA5 */ + mx31_set_pad(MX31_PIN_SRXD3, H2_PAD_CFG); /* USBH2_DATA6 */ + mx31_set_pad(MX31_PIN_STXD3, H2_PAD_CFG); /* USBH2_DATA7 */ + + writel(readl((IOMUXC_BASE + 0x8)) | (1 << 11), IOMUXC_BASE + 0x8); + return 0; } diff --git a/include/configs/qong.h b/include/configs/qong.h index 0465ff4..b1aca93 100644 --- a/include/configs/qong.h +++ b/include/configs/qong.h @@ -89,6 +89,22 @@ #define CONFIG_BMP_16BPP #define CONFIG_DISPLAY_COM57H5M10XRC +/* USB */ +#define CONFIG_CMD_USB +#ifdef CONFIG_CMD_USB +#define CONFIG_USB_EHCI /* Enable EHCI USB support */ +#define CONFIG_USB_EHCI_MXC +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET +#define CONFIG_MXC_USB_PORT 2 +#define CONFIG_MXC_USB_PORTSC (MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT) +#define CONFIG_MXC_USB_FLAGS MXC_EHCI_POWER_PINS_ENABLED +#define CONFIG_EHCI_IS_TDI +#define CONFIG_USB_STORAGE +#define CONFIG_DOS_PARTITION +#define CONFIG_SUPPORT_VFAT +#define CONFIG_CMD_FAT +#endif /* CONFIG_CMD_USB */ + /* * Reducing the ARP timeout from default 5 seconds to 200ms we speed up the * initial TFTP transfer, should the user wish one, significantly. @@ -250,7 +266,7 @@ extern int qong_nand_rdy(void *chip); #define CONFIG_ENV_IS_IN_FLASH 1 #define CONFIG_ENV_SECT_SIZE 0x20000 #define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE -#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x60000) +#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x80000) /* Address and size of Redundant Environment Sector */ #define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE) -- cgit v0.10.2 From d470a6f60ad0d627c21a2769513d2017f9a0da76 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Mon, 11 Oct 2010 05:51:39 -0700 Subject: env_mmc: Fix crashing bug encountered after enabling ARM relocation The crash was occuring in env_relocate because it was being called prior to mmc_initialize. This patch moves the MMC initialization earlier in the init process. This patch also cleans up the env_relocate_spec code in env_mmc.c Signed-off-by: Steve Sakoman Acked-by: Stefano Babic diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index 22bd2c9..108e6c4 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -770,6 +770,11 @@ void board_init_r (gd_t *id, ulong dest_addr) onenand_init(); #endif +#ifdef CONFIG_GENERIC_MMC + puts("MMC: "); + mmc_initialize(bd); +#endif + #ifdef CONFIG_HAS_DATAFLASH AT91F_DataflashInit(); dataflash_print_info(); @@ -835,11 +840,6 @@ void board_init_r (gd_t *id, ulong dest_addr) board_late_init (); #endif -#ifdef CONFIG_GENERIC_MMC - puts ("MMC: "); - mmc_initialize (gd->bd); -#endif - #ifdef CONFIG_BITBANGMII bb_miiphy_init(); #endif diff --git a/common/env_mmc.c b/common/env_mmc.c index cc288d4..d443ff5 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -129,18 +129,21 @@ inline int read_env(struct mmc *mmc, unsigned long size, void env_relocate_spec(void) { #if !defined(ENV_IS_EMBEDDED) + char buf[CONFIG_ENV_SIZE]; + struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); - if (init_mmc_for_env(mmc)) + if (init_mmc_for_env(mmc)) { + use_default(); return; + } - if (read_env(mmc, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, env_ptr)) - return use_default(); - - if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) - return use_default(); + if (read_env(mmc, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, buf)) { + use_default(); + return; + } - gd->env_valid = 1; + env_import(buf, 1); #endif } -- cgit v0.10.2 From edad84c299628154ad14ad3726fc22ff45800830 Mon Sep 17 00:00:00 2001 From: Loic Minier Date: Wed, 13 Oct 2010 14:37:14 -0600 Subject: mx51evk: add u-boot.imx to ALL target Signed-off-by: Loic Minier CC: stefano babic diff --git a/board/freescale/mx51evk/config.mk b/board/freescale/mx51evk/config.mk index af70ec2..dd4a2c2 100644 --- a/board/freescale/mx51evk/config.mk +++ b/board/freescale/mx51evk/config.mk @@ -23,3 +23,4 @@ LDSCRIPT = $(CPUDIR)/$(SOC)/u-boot.lds TEXT_BASE = 0x97800000 IMX_CONFIG = $(SRCTREE)/board/$(BOARDDIR)/imximage.cfg +ALL += $(obj)u-boot.imx -- cgit v0.10.2 From 7b7903ec6a1c693c98e9dea512b91eb59cfd0cf6 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Mon, 27 Sep 2010 14:46:34 -0700 Subject: ARMV7: OMAP: Use default vendor/product ID for USB gadget TI hasn't reserved a USB Product ID for gadgets, so use the default vendor and product ID to avoid confusion. Signed-off-by: Steve Sakoman diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h index 1bd0f37..6f4ee28 100644 --- a/include/configs/omap3_beagle.h +++ b/include/configs/omap3_beagle.h @@ -111,11 +111,6 @@ #define CONFIG_USB_DEVICE 1 #define CONFIG_USB_TTY 1 #define CONFIG_SYS_CONSOLE_IS_IN_ENV 1 -/* Change these to suit your needs */ -#define CONFIG_USBD_VENDORID 0x0451 -#define CONFIG_USBD_PRODUCTID 0x5678 -#define CONFIG_USBD_MANUFACTURER "Texas Instruments" -#define CONFIG_USBD_PRODUCT_NAME "Beagle" /* commands to include */ #include diff --git a/include/configs/omap4_panda.h b/include/configs/omap4_panda.h index a0d27a4..d4a1d1c 100644 --- a/include/configs/omap4_panda.h +++ b/include/configs/omap4_panda.h @@ -120,11 +120,6 @@ #define CONFIG_USB_DEVICE 1 #define CONFIG_USB_TTY 1 #define CONFIG_SYS_CONSOLE_IS_IN_ENV 1 -/* Change these to suit your needs */ -#define CONFIG_USBD_VENDORID 0x0451 -#define CONFIG_USBD_PRODUCTID 0x5678 -#define CONFIG_USBD_MANUFACTURER "Texas Instruments" -#define CONFIG_USBD_PRODUCT_NAME "OMAP4 Panda" /* Flash */ #define CONFIG_SYS_NO_FLASH 1 diff --git a/include/configs/omap4_sdp4430.h b/include/configs/omap4_sdp4430.h index d5439f9..98a86c3 100644 --- a/include/configs/omap4_sdp4430.h +++ b/include/configs/omap4_sdp4430.h @@ -121,11 +121,6 @@ #define CONFIG_USB_DEVICE 1 #define CONFIG_USB_TTY 1 #define CONFIG_SYS_CONSOLE_IS_IN_ENV 1 -/* Change these to suit your needs */ -#define CONFIG_USBD_VENDORID 0x0451 -#define CONFIG_USBD_PRODUCTID 0x5678 -#define CONFIG_USBD_MANUFACTURER "Texas Instruments" -#define CONFIG_USBD_PRODUCT_NAME "SDP4430" /* Flash */ #define CONFIG_SYS_NO_FLASH 1 -- cgit v0.10.2 From d23e2c09a7900ec4c208e602b608ae2399e6d536 Mon Sep 17 00:00:00 2001 From: Sukumar Ghorai Date: Mon, 20 Sep 2010 18:29:29 +0530 Subject: MMC: Fix for capacity calculation on eMMC The current mmc driver returns erroneous capacity information for eMMC. The capacity of eMMC devices is available only in the ext-CSD register. This patch add code to read the ext-CDSD register and correctly calculate eMMC capacity. Signed-off-by: Sukumar Ghorai Acked-by: Steve Sakoman diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 80cd9bf..c543d83 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -627,6 +627,7 @@ int mmc_startup(struct mmc *mmc) uint mult, freq; u64 cmult, csize; struct mmc_cmd cmd; + char ext_csd[512]; /* Put the Card in Identify Mode */ cmd.cmdidx = MMC_CMD_ALL_SEND_CID; @@ -742,6 +743,16 @@ int mmc_startup(struct mmc *mmc) if (err) return err; + if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) { + /* check ext_csd version and capacity */ + err = mmc_send_ext_csd(mmc, ext_csd); + if (!err & (ext_csd[192] >= 2)) { + mmc->capacity = ext_csd[212] << 0 | ext_csd[213] << 8 | + ext_csd[214] << 16 | ext_csd[215] << 24; + mmc->capacity *= 512; + } + } + if (IS_SD(mmc)) err = sd_change_freq(mmc); else -- cgit v0.10.2 From de941241a0d6a5f00e3273112c2cf8535e4f15af Mon Sep 17 00:00:00 2001 From: Sukumar Ghorai Date: Sat, 18 Sep 2010 20:32:33 -0700 Subject: ARMV7: OMAP: Add new mmc driver compatible with CONFIG_GENERIC_MMC OMAP boards currently use a legacy mmc driver. This patch adds a new mmc driver which will work with the generic mmc driver in u-boot. This new driver will work with both OMAP3 and OMAP4 boards. This patch does not remove the old driver. It should remain in the tree until all boards that use it switch to the new driver. Signed-off-by: Sukumar Ghorai Tested-by: Steve Sakoman diff --git a/arch/arm/include/asm/arch-omap3/mmc_host_def.h b/arch/arm/include/asm/arch-omap3/mmc_host_def.h index 43dd705..ba1c2ff 100644 --- a/arch/arm/include/asm/arch-omap3/mmc_host_def.h +++ b/arch/arm/include/asm/arch-omap3/mmc_host_def.h @@ -102,12 +102,14 @@ typedef struct hsmmc { #define NBLK_STPCNT (0x0 << 16) #define DE_DISABLE (0x0 << 0) #define BCE_DISABLE (0x0 << 1) +#define BCE_ENABLE (0x1 << 1) #define ACEN_DISABLE (0x0 << 2) #define DDIR_OFFSET (4) #define DDIR_MASK (0x1 << 4) #define DDIR_WRITE (0x0 << 4) #define DDIR_READ (0x1 << 4) #define MSBS_SGLEBLK (0x0 << 5) +#define MSBS_MULTIBLK (0x1 << 5) #define RSP_TYPE_OFFSET (16) #define RSP_TYPE_MASK (0x3 << 16) #define RSP_TYPE_NORSP (0x0 << 16) @@ -130,6 +132,7 @@ typedef struct hsmmc { #define DATI_CMDDIS (0x1 << 1) #define DTW_1_BITMODE (0x0 << 1) #define DTW_4_BITMODE (0x1 << 1) +#define DTW_8_BITMODE (0x1 << 5) /* CON[DW8]*/ #define SDBP_PWROFF (0x0 << 8) #define SDBP_PWRON (0x1 << 8) #define SDVS_1V8 (0x5 << 9) @@ -186,8 +189,15 @@ typedef struct { unsigned int size; unsigned int RCA; } mmc_card_data; +#define RSP_TYPE_NONE (RSP_TYPE_NORSP | CCCE_NOCHECK | CICE_NOCHECK) +#define MMC_CMD0 (INDEX(0) | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE) + +/* Clock Configurations and Macros */ +#define MMC_CLOCK_REFERENCE 96 /* MHz */ #define mmc_reg_out(addr, mask, val)\ writel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr)) +int omap_mmc_init(int dev_index); + #endif /* MMC_HOST_DEF_H */ diff --git a/arch/arm/include/asm/arch-omap4/mmc_host_def.h b/arch/arm/include/asm/arch-omap4/mmc_host_def.h index e5d8b53..733d8ed 100644 --- a/arch/arm/include/asm/arch-omap4/mmc_host_def.h +++ b/arch/arm/include/asm/arch-omap4/mmc_host_def.h @@ -80,12 +80,14 @@ typedef struct hsmmc { #define NBLK_STPCNT (0x0 << 16) #define DE_DISABLE (0x0 << 0) #define BCE_DISABLE (0x0 << 1) +#define BCE_ENABLE (0x1 << 1) #define ACEN_DISABLE (0x0 << 2) #define DDIR_OFFSET (4) #define DDIR_MASK (0x1 << 4) #define DDIR_WRITE (0x0 << 4) #define DDIR_READ (0x1 << 4) #define MSBS_SGLEBLK (0x0 << 5) +#define MSBS_MULTIBLK (0x1 << 5) #define RSP_TYPE_OFFSET (16) #define RSP_TYPE_MASK (0x3 << 16) #define RSP_TYPE_NORSP (0x0 << 16) @@ -108,6 +110,7 @@ typedef struct hsmmc { #define DATI_CMDDIS (0x1 << 1) #define DTW_1_BITMODE (0x0 << 1) #define DTW_4_BITMODE (0x1 << 1) +#define DTW_8_BITMODE (0x1 << 5) /* CON[DW8]*/ #define SDBP_PWROFF (0x0 << 8) #define SDBP_PWRON (0x1 << 8) #define SDVS_1V8 (0x5 << 9) @@ -164,8 +167,15 @@ typedef struct { unsigned int size; unsigned int RCA; } mmc_card_data; +#define RSP_TYPE_NONE (RSP_TYPE_NORSP | CCCE_NOCHECK | CICE_NOCHECK) +#define MMC_CMD0 (INDEX(0) | RSP_TYPE_NONE | DP_NO_DATA | DDIR_WRITE) + +/* Clock Configurations and Macros */ +#define MMC_CLOCK_REFERENCE 96 /* MHz */ #define mmc_reg_out(addr, mask, val)\ writel((readl(addr) & (~(mask))) | ((val) & (mask)), (addr)) +int omap_mmc_init(int dev_index); + #endif /* MMC_HOST_DEF_H */ diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 6603d74..2ead634 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -32,6 +32,7 @@ COBJS-$(CONFIG_GENERIC_MMC) += mmc.o COBJS-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o +COBJS-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o COBJS-$(CONFIG_PXA_MMC) += pxa_mmc.o COBJS-$(CONFIG_S5P_MMC) += s5p_mmc.o diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c new file mode 100644 index 0000000..9271470 --- /dev/null +++ b/drivers/mmc/omap_hsmmc.c @@ -0,0 +1,415 @@ +/* + * (C) Copyright 2008 + * Texas Instruments, + * Sukumar Ghorai + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation's version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static int mmc_read_data(hsmmc_t *mmc_base, char *buf, unsigned int size); +static int mmc_write_data(hsmmc_t *mmc_base, const char *buf, unsigned int siz); +static struct mmc hsmmc_dev[2]; +unsigned char mmc_board_init(hsmmc_t *mmc_base) +{ +#if defined(CONFIG_TWL4030_POWER) + twl4030_power_mmc_init(); +#endif + +#if defined(CONFIG_OMAP34XX) + t2_t *t2_base = (t2_t *)T2_BASE; + struct prcm *prcm_base = (struct prcm *)PRCM_BASE; + + writel(readl(&t2_base->pbias_lite) | PBIASLITEPWRDNZ1 | + PBIASSPEEDCTRL0 | PBIASLITEPWRDNZ0, + &t2_base->pbias_lite); + + writel(readl(&t2_base->devconf0) | MMCSDIO1ADPCLKISEL, + &t2_base->devconf0); + + writel(readl(&t2_base->devconf1) | MMCSDIO2ADPCLKISEL, + &t2_base->devconf1); + + writel(readl(&prcm_base->fclken1_core) | + EN_MMC1 | EN_MMC2 | EN_MMC3, + &prcm_base->fclken1_core); + + writel(readl(&prcm_base->iclken1_core) | + EN_MMC1 | EN_MMC2 | EN_MMC3, + &prcm_base->iclken1_core); +#endif + +/* TODO add appropriate OMAP4 init - none currently necessary */ + + return 0; +} + +void mmc_init_stream(hsmmc_t *mmc_base) +{ + + writel(readl(&mmc_base->con) | INIT_INITSTREAM, &mmc_base->con); + + writel(MMC_CMD0, &mmc_base->cmd); + while (!(readl(&mmc_base->stat) & CC_MASK)) + ; + writel(CC_MASK, &mmc_base->stat) + ; + writel(MMC_CMD0, &mmc_base->cmd) + ; + while (!(readl(&mmc_base->stat) & CC_MASK)) + ; + writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con); +} + + +static int mmc_init_setup(struct mmc *mmc) +{ + hsmmc_t *mmc_base = (hsmmc_t *)mmc->priv; + unsigned int reg_val; + unsigned int dsor; + + mmc_board_init(mmc_base); + + writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET, + &mmc_base->sysconfig); + while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) + ; + writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl); + while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0) + ; + writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl); + writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP, + &mmc_base->capa); + + reg_val = readl(&mmc_base->con) & RESERVED_MASK; + + writel(CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | CDP_ACTIVEHIGH | + MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | STR_BLOCK | + HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN, &mmc_base->con); + + dsor = 240; + mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK), + (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); + mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK, + (dsor << CLKD_OFFSET) | ICE_OSCILLATE); + while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) + ; + writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); + + writel(readl(&mmc_base->hctl) | SDBP_PWRON, &mmc_base->hctl); + + writel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE | + IE_CEB | IE_CCRC | IE_CTO | IE_BRR | IE_BWR | IE_TC | IE_CC, + &mmc_base->ie); + + mmc_init_stream(mmc_base); + + return 0; +} + + +static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + hsmmc_t *mmc_base = (hsmmc_t *)mmc->priv; + unsigned int flags, mmc_stat; + unsigned int retry = 0x100000; + + + while ((readl(&mmc_base->pstate) & DATI_MASK) == DATI_CMDDIS) + ; + writel(0xFFFFFFFF, &mmc_base->stat); + while (readl(&mmc_base->stat)) + ; + /* + * CMDREG + * CMDIDX[13:8] : Command index + * DATAPRNT[5] : Data Present Select + * ENCMDIDX[4] : Command Index Check Enable + * ENCMDCRC[3] : Command CRC Check Enable + * RSPTYP[1:0] + * 00 = No Response + * 01 = Length 136 + * 10 = Length 48 + * 11 = Length 48 Check busy after response + */ + /* Delay added before checking the status of frq change + * retry not supported by mmc.c(core file) + */ + if (cmd->cmdidx == SD_CMD_APP_SEND_SCR) + udelay(50000); /* wait 50 ms */ + + if (!(cmd->resp_type & MMC_RSP_PRESENT)) + flags = 0; + else if (cmd->resp_type & MMC_RSP_136) + flags = RSP_TYPE_LGHT136 | CICE_NOCHECK; + else if (cmd->resp_type & MMC_RSP_BUSY) + flags = RSP_TYPE_LGHT48B; + else + flags = RSP_TYPE_LGHT48; + + /* enable default flags */ + flags = flags | (CMD_TYPE_NORMAL | CICE_NOCHECK | CCCE_NOCHECK | + MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | DE_DISABLE); + + if (cmd->resp_type & MMC_RSP_CRC) + flags |= CCCE_CHECK; + if (cmd->resp_type & MMC_RSP_OPCODE) + flags |= CICE_CHECK; + + if (data) { + if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) || + (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) { + flags |= (MSBS_MULTIBLK | BCE_ENABLE); + data->blocksize = 512; + writel(data->blocksize | (data->blocks << 16), + &mmc_base->blk); + } else + writel(data->blocksize | NBLK_STPCNT, &mmc_base->blk); + + if (data->flags & MMC_DATA_READ) + flags |= (DP_DATA | DDIR_READ); + else + flags |= (DP_DATA | DDIR_WRITE); + } + + writel(cmd->cmdarg, &mmc_base->arg); + writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd); + + do { + mmc_stat = readl(&mmc_base->stat); + retry--; + } while ((mmc_stat == 0) && (retry > 0)); + + if (retry == 0) { + printf("%s : timeout: No status update\n", __func__); + return TIMEOUT; + } + + if ((mmc_stat & IE_CTO) != 0) + return TIMEOUT; + else if ((mmc_stat & ERRI_MASK) != 0) + return -1; + + if (mmc_stat & CC_MASK) { + writel(CC_MASK, &mmc_base->stat); + if (cmd->resp_type & MMC_RSP_PRESENT) { + if (cmd->resp_type & MMC_RSP_136) { + /* response type 2 */ + cmd->response[3] = readl(&mmc_base->rsp10); + cmd->response[2] = readl(&mmc_base->rsp32); + cmd->response[1] = readl(&mmc_base->rsp54); + cmd->response[0] = readl(&mmc_base->rsp76); + } else + /* response types 1, 1b, 3, 4, 5, 6 */ + cmd->response[0] = readl(&mmc_base->rsp10); + } + } + + if (data && (data->flags & MMC_DATA_READ)) { + mmc_read_data(mmc_base, data->dest, + data->blocksize * data->blocks); + } else if (data && (data->flags & MMC_DATA_WRITE)) { + mmc_write_data(mmc_base, data->src, + data->blocksize * data->blocks); + } + return 0; +} + +static int mmc_read_data(hsmmc_t *mmc_base, char *buf, unsigned int size) +{ + unsigned int *output_buf = (unsigned int *)buf; + unsigned int mmc_stat; + unsigned int count; + + /* + * Start Polled Read + */ + count = (size > MMCSD_SECTOR_SIZE) ? MMCSD_SECTOR_SIZE : size; + count /= 4; + + while (size) { + do { + mmc_stat = readl(&mmc_base->stat); + } while (mmc_stat == 0); + + if ((mmc_stat & ERRI_MASK) != 0) + return 1; + + if (mmc_stat & BRR_MASK) { + unsigned int k; + + writel(readl(&mmc_base->stat) | BRR_MASK, + &mmc_base->stat); + for (k = 0; k < count; k++) { + *output_buf = readl(&mmc_base->data); + output_buf++; + } + size -= (count*4); + } + + if (mmc_stat & BWR_MASK) + writel(readl(&mmc_base->stat) | BWR_MASK, + &mmc_base->stat); + + if (mmc_stat & TC_MASK) { + writel(readl(&mmc_base->stat) | TC_MASK, + &mmc_base->stat); + break; + } + } + return 0; +} + +static int mmc_write_data(hsmmc_t *mmc_base, const char *buf, unsigned int size) +{ + unsigned int *input_buf = (unsigned int *)buf; + unsigned int mmc_stat; + unsigned int count; + + /* + * Start Polled Read + */ + count = (size > MMCSD_SECTOR_SIZE) ? MMCSD_SECTOR_SIZE : size; + count /= 4; + + while (size) { + do { + mmc_stat = readl(&mmc_base->stat); + } while (mmc_stat == 0); + + if ((mmc_stat & ERRI_MASK) != 0) + return 1; + + if (mmc_stat & BWR_MASK) { + unsigned int k; + + writel(readl(&mmc_base->stat) | BWR_MASK, + &mmc_base->stat); + for (k = 0; k < count; k++) { + writel(*input_buf, &mmc_base->data); + input_buf++; + } + size -= (count*4); + } + + if (mmc_stat & BRR_MASK) + writel(readl(&mmc_base->stat) | BRR_MASK, + &mmc_base->stat); + + if (mmc_stat & TC_MASK) { + writel(readl(&mmc_base->stat) | TC_MASK, + &mmc_base->stat); + break; + } + } + return 0; +} + +static void mmc_set_ios(struct mmc *mmc) +{ + hsmmc_t *mmc_base = (hsmmc_t *)mmc->priv; + unsigned int dsor = 0; + + /* configue bus width */ + switch (mmc->bus_width) { + case 8: + writel(readl(&mmc_base->con) | DTW_8_BITMODE, + &mmc_base->con); + break; + + case 4: + writel(readl(&mmc_base->con) & ~DTW_8_BITMODE, + &mmc_base->con); + writel(readl(&mmc_base->hctl) | DTW_4_BITMODE, + &mmc_base->hctl); + break; + + case 1: + default: + writel(readl(&mmc_base->con) & ~DTW_8_BITMODE, + &mmc_base->con); + writel(readl(&mmc_base->hctl) & ~DTW_4_BITMODE, + &mmc_base->hctl); + break; + } + + /* configure clock with 96Mhz system clock. + */ + if (mmc->clock != 0) { + dsor = (MMC_CLOCK_REFERENCE * 1000000 / mmc->clock); + if ((MMC_CLOCK_REFERENCE * 1000000) / dsor > mmc->clock) + dsor++; + } + + mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK), + (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); + + mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK, + (dsor << CLKD_OFFSET) | ICE_OSCILLATE); + + while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) + ; + writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); +} + +int omap_mmc_init(int dev_index) +{ + struct mmc *mmc; + + mmc = &hsmmc_dev[dev_index]; + + sprintf(mmc->name, "OMAP SD/MMC"); + mmc->send_cmd = mmc_send_cmd; + mmc->set_ios = mmc_set_ios; + mmc->init = mmc_init_setup; + + switch (dev_index) { + case 0: + mmc->priv = (hsmmc_t *)OMAP_HSMMC1_BASE; + break; + case 1: + mmc->priv = (hsmmc_t *)OMAP_HSMMC2_BASE; + break; + case 2: + mmc->priv = (hsmmc_t *)OMAP_HSMMC3_BASE; + break; + default: + mmc->priv = (hsmmc_t *)OMAP_HSMMC1_BASE; + return 1; + } + mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; + mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS; + + mmc->f_min = 400000; + mmc->f_max = 52000000; + + mmc_register(mmc); + + return 0; +} + -- cgit v0.10.2 From 7e982c956d74614fc59cacf39016fad8bbb194ed Mon Sep 17 00:00:00 2001 From: Sukumar Ghorai Date: Sat, 18 Sep 2010 20:56:18 -0700 Subject: ARMV7: OMAP4: Use generic mmc driver on Panda This patch switches from the legacy mmc driver to the new generic mmc driver Signed-off-by: Sukumar Ghorai Tested-by: Steve Sakoman diff --git a/board/ti/panda/panda.c b/board/ti/panda/panda.c index 1b8153b..78e1910 100644 --- a/board/ti/panda/panda.c +++ b/board/ti/panda/panda.c @@ -23,6 +23,7 @@ */ #include #include +#include #include "panda.h" @@ -87,3 +88,11 @@ void set_muxconf_regs(void) sizeof(wkup_padconf_array) / sizeof(struct pad_conf_entry)); } + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + omap_mmc_init(0); + return 0; +} +#endif diff --git a/include/configs/omap4_panda.h b/include/configs/omap4_panda.h index d4a1d1c..2618f7d 100644 --- a/include/configs/omap4_panda.h +++ b/include/configs/omap4_panda.h @@ -89,7 +89,6 @@ #define CONFIG_SYS_NS16550_COM3 UART3_BASE #define CONFIG_ENV_IS_NOWHERE -#define CONFIG_ENV_OVERWRITE #define CONFIG_BAUDRATE 115200 #define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ 115200} @@ -107,8 +106,9 @@ #define CONFIG_TWL6030_POWER 1 /* MMC */ +#define CONFIG_GENERIC_MMC 1 #define CONFIG_MMC 1 -#define CONFIG_OMAP3_MMC 1 +#define CONFIG_OMAP_HSMMC 1 #define CONFIG_SYS_MMC_SET_DEV 1 #define CONFIG_DOS_PARTITION 1 @@ -150,7 +150,6 @@ #define CONFIG_BOOTDELAY 3 -/* allow overwriting serial config and ethaddr */ #define CONFIG_ENV_OVERWRITE #define CONFIG_EXTRA_ENV_SETTINGS \ @@ -158,7 +157,7 @@ "console=ttyS2,115200n8\0" \ "usbtty=cdc_acm\0" \ "vram=16M\0" \ - "mmcdev=1\0" \ + "mmcdev=0\0" \ "mmcroot=/dev/mmcblk0p2 rw\0" \ "mmcrootfstype=ext3 rootwait\0" \ "mmcargs=setenv bootargs console=${console} " \ @@ -174,7 +173,7 @@ "bootm ${loadaddr}\0" \ #define CONFIG_BOOTCOMMAND \ - "if mmc init ${mmcdev}; then " \ + "if mmc rescan ${mmcdev}; then " \ "if run loadbootscript; then " \ "run bootscript; " \ "else " \ -- cgit v0.10.2 From 084c4c1bc10ef7abd64eebaf4c0a559409c82ddb Mon Sep 17 00:00:00 2001 From: Sukumar Ghorai Date: Sat, 18 Sep 2010 20:59:54 -0700 Subject: ARMV7: OMAP4: Use generic mmc driver on SDP4430 This patch switches from the legacy mmc driver to the new generic mmc driver Signed-off-by: Sukumar Ghorai Tested-by: Steve Sakoman diff --git a/board/ti/sdp4430/sdp.c b/board/ti/sdp4430/sdp.c index 7039bd5..01d5ce4 100644 --- a/board/ti/sdp4430/sdp.c +++ b/board/ti/sdp4430/sdp.c @@ -24,6 +24,7 @@ */ #include #include +#include #include "sdp.h" @@ -88,3 +89,12 @@ void set_muxconf_regs(void) sizeof(wkup_padconf_array) / sizeof(struct pad_conf_entry)); } + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + omap_mmc_init(0); + omap_mmc_init(1); + return 0; +} +#endif diff --git a/include/configs/omap4_sdp4430.h b/include/configs/omap4_sdp4430.h index 98a86c3..1241b1e 100644 --- a/include/configs/omap4_sdp4430.h +++ b/include/configs/omap4_sdp4430.h @@ -90,7 +90,7 @@ #define CONFIG_SYS_NS16550_COM3 UART3_BASE #define CONFIG_ENV_IS_NOWHERE -#define CONFIG_ENV_OVERWRITE + #define CONFIG_BAUDRATE 115200 #define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ 115200} @@ -108,8 +108,9 @@ #define CONFIG_TWL6030_POWER 1 /* MMC */ +#define CONFIG_GENERIC_MMC 1 #define CONFIG_MMC 1 -#define CONFIG_OMAP3_MMC 1 +#define CONFIG_OMAP_HSMMC 1 #define CONFIG_SYS_MMC_SET_DEV 1 #define CONFIG_DOS_PARTITION 1 @@ -151,7 +152,6 @@ #define CONFIG_BOOTDELAY 3 -/* allow overwriting serial config and ethaddr */ #define CONFIG_ENV_OVERWRITE #define CONFIG_EXTRA_ENV_SETTINGS \ @@ -159,7 +159,7 @@ "console=ttyS2,115200n8\0" \ "usbtty=cdc_acm\0" \ "vram=16M\0" \ - "mmcdev=1\0" \ + "mmcdev=0\0" \ "mmcroot=/dev/mmcblk0p2 rw\0" \ "mmcrootfstype=ext3 rootwait\0" \ "mmcargs=setenv bootargs console=${console} " \ @@ -175,7 +175,7 @@ "bootm ${loadaddr}\0" \ #define CONFIG_BOOTCOMMAND \ - "if mmc init ${mmcdev}; then " \ + "if mmc rescan ${mmcdev}; then " \ "if run loadbootscript; then " \ "run bootscript; " \ "else " \ -- cgit v0.10.2 From 0cd31144240221a4f6b35615f1af9159fb20b266 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Sun, 19 Sep 2010 21:19:48 -0700 Subject: ARMV7: OMAP4: Use generic mmc driver on Beagle This patch switches from the legacy mmc driver to the new generic mmc driver Signed-off-by: Steve Sakoman diff --git a/board/ti/beagle/beagle.c b/board/ti/beagle/beagle.c index 4647908..c5d6679 100644 --- a/board/ti/beagle/beagle.c +++ b/board/ti/beagle/beagle.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -169,3 +170,11 @@ void set_muxconf_regs(void) { MUX_BEAGLE(); } + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + omap_mmc_init(0); + return 0; +} +#endif diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h index 6f4ee28..bbb1073 100644 --- a/include/configs/omap3_beagle.h +++ b/include/configs/omap3_beagle.h @@ -95,8 +95,9 @@ #define CONFIG_BAUDRATE 115200 #define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ 115200} +#define CONFIG_GENERIC_MMC 1 #define CONFIG_MMC 1 -#define CONFIG_OMAP3_MMC 1 +#define CONFIG_OMAP_HSMMC 1 #define CONFIG_DOS_PARTITION 1 /* DDR - I use Micron DDR */ @@ -184,6 +185,7 @@ "vram=12M\0" \ "dvimode=1024x768MR-16@60\0" \ "defaultdisplay=dvi\0" \ + "mmcdev=0\0" \ "mmcroot=/dev/mmcblk0p2 rw\0" \ "mmcrootfstype=ext3 rootwait\0" \ "nandroot=/dev/mtdblock4 rw\0" \ @@ -204,10 +206,10 @@ "omapdss.def_disp=${defaultdisplay} " \ "root=${nandroot} " \ "rootfstype=${nandrootfstype}\0" \ - "loadbootscript=fatload mmc 0 ${loadaddr} boot.scr\0" \ + "loadbootscript=fatload mmc ${mmcdev} ${loadaddr} boot.scr\0" \ "bootscript=echo Running bootscript from mmc ...; " \ "source ${loadaddr}\0" \ - "loaduimage=fatload mmc 0 ${loadaddr} uImage\0" \ + "loaduimage=fatload mmc ${mmcdev} ${loadaddr} uImage\0" \ "mmcboot=echo Booting from mmc ...; " \ "run mmcargs; " \ "bootm ${loadaddr}\0" \ @@ -217,7 +219,7 @@ "bootm ${loadaddr}\0" \ #define CONFIG_BOOTCOMMAND \ - "if mmc init; then " \ + "if mmc rescan ${mmcdev}; then " \ "if run loadbootscript; then " \ "run bootscript; " \ "else " \ -- cgit v0.10.2 From cd7c57262f929c3ce73bb68484989bc243752438 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Sun, 19 Sep 2010 21:21:07 -0700 Subject: ARMV7: OMAP4: Use generic mmc driver on Overo This patch switches from the legacy mmc driver to the new generic mmc driver Signed-off-by: Steve Sakoman diff --git a/board/overo/overo.c b/board/overo/overo.c index 1b67f1f..9c92693 100644 --- a/board/overo/overo.c +++ b/board/overo/overo.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -225,3 +226,11 @@ int board_eth_init(bd_t *bis) #endif return rc; } + +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + omap_mmc_init(0); + return 0; +} +#endif diff --git a/include/configs/omap3_overo.h b/include/configs/omap3_overo.h index a0e0f24..0d2ed44 100644 --- a/include/configs/omap3_overo.h +++ b/include/configs/omap3_overo.h @@ -87,8 +87,9 @@ #define CONFIG_BAUDRATE 115200 #define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, \ 115200} +#define CONFIG_GENERIC_MMC 1 #define CONFIG_MMC 1 -#define CONFIG_OMAP3_MMC 1 +#define CONFIG_OMAP_HSMMC 1 #define CONFIG_DOS_PARTITION 1 /* DDR - I use Micron DDR */ @@ -158,6 +159,7 @@ "vram=12M\0" \ "dvimode=1024x768MR-16@60\0" \ "defaultdisplay=dvi\0" \ + "mmcdev=0\0" \ "mmcroot=/dev/mmcblk0p2 rw\0" \ "mmcrootfstype=ext3 rootwait\0" \ "nandroot=/dev/mtdblock4 rw\0" \ @@ -178,10 +180,10 @@ "omapdss.def_disp=${defaultdisplay} " \ "root=${nandroot} " \ "rootfstype=${nandrootfstype}\0" \ - "loadbootscript=fatload mmc 0 ${loadaddr} boot.scr\0" \ + "loadbootscript=fatload mmc ${mmcdev} ${loadaddr} boot.scr\0" \ "bootscript=echo Running bootscript from mmc ...; " \ "source ${loadaddr}\0" \ - "loaduimage=fatload mmc 0 ${loadaddr} uImage\0" \ + "loaduimage=fatload mmc ${mmcdev} ${loadaddr} uImage\0" \ "mmcboot=echo Booting from mmc ...; " \ "run mmcargs; " \ "bootm ${loadaddr}\0" \ @@ -191,7 +193,7 @@ "bootm ${loadaddr}\0" \ #define CONFIG_BOOTCOMMAND \ - "if mmc init; then " \ + "if mmc rescan ${mmcdev}; then " \ "if run loadbootscript; then " \ "run bootscript; " \ "else " \ -- cgit v0.10.2 From 64455352ad0bf96570ea35e6b65e5b4f066a97e9 Mon Sep 17 00:00:00 2001 From: Sukumar Ghorai Date: Tue, 14 Sep 2010 13:52:34 +0530 Subject: ARMV7: OMAP4: Enable saveenv to eMMC for SDP4430 The SDP4430 does not have onboard NAND, it has eMMC on the second MMC slot. This patch adds support for saving the u-boot environment to eMMC. Signed-off-by: Aneesh V Signed-off-by: Sukumar Ghorai Tested-by: Steve Sakoman diff --git a/include/configs/omap4_sdp4430.h b/include/configs/omap4_sdp4430.h index 1241b1e..8274577 100644 --- a/include/configs/omap4_sdp4430.h +++ b/include/configs/omap4_sdp4430.h @@ -63,10 +63,10 @@ /* * Size of malloc() pool - * Total Size Environment - 256k + * Total Size Environment - 128k * Malloc - add 256k */ -#define CONFIG_ENV_SIZE (256 << 10) +#define CONFIG_ENV_SIZE (128 << 10) #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (256 << 10)) #define CONFIG_SYS_GBL_DATA_SIZE 128 /* bytes reserved for */ /* initial data */ @@ -89,12 +89,9 @@ #define CONFIG_CONS_INDEX 3 #define CONFIG_SYS_NS16550_COM3 UART3_BASE -#define CONFIG_ENV_IS_NOWHERE - #define CONFIG_BAUDRATE 115200 #define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ 115200} - /* I2C */ #define CONFIG_HARD_I2C 1 #define CONFIG_SYS_I2C_SPEED 100000 @@ -114,6 +111,11 @@ #define CONFIG_SYS_MMC_SET_DEV 1 #define CONFIG_DOS_PARTITION 1 +/* MMC ENV related defines */ +#define CONFIG_ENV_IS_IN_MMC 1 +#define CONFIG_SYS_MMC_ENV_DEV 1 /* SLOT2: eMMC(1) */ +#define CONFIG_ENV_OFFSET 0xE0000 + /* USB */ #define CONFIG_MUSB_UDC 1 #define CONFIG_USB_OMAP3 1 @@ -134,6 +136,7 @@ #define CONFIG_CMD_FAT /* FAT support */ #define CONFIG_CMD_I2C /* I2C serial bus support */ #define CONFIG_CMD_MMC /* MMC support */ +#define CONFIG_CMD_SAVEENV /* Disabled commands */ #undef CONFIG_CMD_NET -- cgit v0.10.2 From 4d7d7bc36d3ef71b4808731b345c8f68c8bed6a4 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Wed, 29 Sep 2010 13:54:19 -0700 Subject: ARMV7: OMAP3: Implement relocation for Overo This patch fixes the build breakage introduced by the recent relocation changes for ARMV7 Signed-off-by: Steve Sakoman diff --git a/board/overo/config.mk b/board/overo/config.mk index d372fd9..59b651f 100644 --- a/board/overo/config.mk +++ b/board/overo/config.mk @@ -26,4 +26,4 @@ # (mem base + reserved) # For use with external or internal boots. -TEXT_BASE = 0x80e80000 +TEXT_BASE = 0x80008000 diff --git a/include/configs/omap3_overo.h b/include/configs/omap3_overo.h index 0d2ed44..d7c7b0f 100644 --- a/include/configs/omap3_overo.h +++ b/include/configs/omap3_overo.h @@ -323,4 +323,7 @@ extern unsigned int boot_flash_type; #endif /* (CONFIG_CMD_NET) */ +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 +#define CONFIG_SYS_INIT_SP_ADDR (LOW_LEVEL_SRAM_STACK - CONFIG_SYS_GBL_DATA_SIZE) + #endif /* __CONFIG_H */ -- cgit v0.10.2 From 68b0fbf08574ac2314919ce8fad9a1965041cc44 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Wed, 29 Sep 2010 13:58:34 -0700 Subject: ARMV7: OMAP3: Enable cache support on Overo Signed-off-by: Steve Sakoman diff --git a/include/configs/omap3_overo.h b/include/configs/omap3_overo.h index d7c7b0f..69f9126 100644 --- a/include/configs/omap3_overo.h +++ b/include/configs/omap3_overo.h @@ -98,6 +98,7 @@ /* commands to include */ #include +#define CONFIG_CMD_CACHE #define CONFIG_CMD_EXT2 /* EXT2 Support */ #define CONFIG_CMD_FAT /* FAT support */ #define CONFIG_CMD_JFFS2 /* JFFS2 Support */ -- cgit v0.10.2 From 136c69ad7917f23d401c3a794cd0f5a4ab2230de Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Thu, 30 Sep 2010 21:46:52 -0700 Subject: ARMV7: OMAP3: Fix bug in get_sdr_cs_offset() This patch fixes a typo in the routine to calculate the cs offset based upon the contents of the SDRC cs_cfg register. This function mistakenly shifts the CS1STARTLOW field 17 bits right instead of 17 bits left. This hasn't been an issue to date because all OMAP3 boards currently are configured to have zeros in this field. Reported-by: Peter Maydell Signed-off-by: Steve Sakoman diff --git a/arch/arm/cpu/armv7/omap3/sdrc.c b/arch/arm/cpu/armv7/omap3/sdrc.c index 2719bb5..6c419f5 100644 --- a/arch/arm/cpu/armv7/omap3/sdrc.c +++ b/arch/arm/cpu/armv7/omap3/sdrc.c @@ -99,7 +99,7 @@ u32 get_sdr_cs_offset(u32 cs) return 0; offset = readl(&sdrc_base->cs_cfg); - offset = (offset & 15) << 27 | (offset & 0x30) >> 17; + offset = (offset & 15) << 27 | (offset & 0x30) << 17; return offset; } -- cgit v0.10.2 From 57b512b2ecc9c7a6c8a39c5356ea80fc3164d9e4 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Wed, 29 Sep 2010 20:59:51 -0700 Subject: ARMV7: OMAP4: Implement relocation for Panda and OMAP4430SDP This patch fixes the build breakage introduced by the recent relocation changes for ARMV7 Signed-off-by: Steve Sakoman diff --git a/arch/arm/cpu/armv7/omap4/board.c b/arch/arm/cpu/armv7/omap4/board.c index 8c1f395..24a66f5 100644 --- a/arch/arm/cpu/armv7/omap4/board.c +++ b/arch/arm/cpu/armv7/omap4/board.c @@ -102,8 +102,13 @@ int dram_init(void) { DECLARE_GLOBAL_DATA_PTR; +#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) gd->bd->bi_dram[0].start = 0x80000000; gd->bd->bi_dram[0].size = sdram_size(); +#else + gd->ram_size = sdram_size(); +#endif + return 0; } diff --git a/board/ti/panda/config.mk b/board/ti/panda/config.mk index 7382263..7176c14 100644 --- a/board/ti/panda/config.mk +++ b/board/ti/panda/config.mk @@ -27,6 +27,4 @@ # 8000'0000 - 9fff'ffff (512 MB) # Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 # (mem base + reserved) - -# Let's place u-boot 1MB before the end of SDRAM. -TEXT_BASE = 0x9ff00000 +TEXT_BASE = 0x80e80000 diff --git a/board/ti/sdp4430/config.mk b/board/ti/sdp4430/config.mk index 7382263..7bb9473 100644 --- a/board/ti/sdp4430/config.mk +++ b/board/ti/sdp4430/config.mk @@ -28,5 +28,4 @@ # Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 # (mem base + reserved) -# Let's place u-boot 1MB before the end of SDRAM. -TEXT_BASE = 0x9ff00000 +TEXT_BASE = 0x80e80000 diff --git a/include/configs/omap4_panda.h b/include/configs/omap4_panda.h index 2618f7d..b52ca19 100644 --- a/include/configs/omap4_panda.h +++ b/include/configs/omap4_panda.h @@ -139,12 +139,6 @@ #undef CONFIG_CMD_IMLS /* List all found images */ /* - * Enabling relocation of u-boot by default - * Relocation can be skipped if u-boot is copied to the TEXT_BASE - */ -#undef CONFIG_SKIP_RELOCATE_UBOOT - -/* * Environment setup */ @@ -233,4 +227,7 @@ */ #define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_SYS_SDRAM_BASE 0x80000000 +#define CONFIG_SYS_INIT_SP_ADDR (LOW_LEVEL_SRAM_STACK - CONFIG_SYS_GBL_DATA_SIZE) + #endif /* __CONFIG_H */ diff --git a/include/configs/omap4_sdp4430.h b/include/configs/omap4_sdp4430.h index 8274577..174d73f 100644 --- a/include/configs/omap4_sdp4430.h +++ b/include/configs/omap4_sdp4430.h @@ -144,12 +144,6 @@ #undef CONFIG_CMD_IMLS /* List all found images */ /* - * Enabling relocation of u-boot by default - * Relocation can be skipped if u-boot is copied to the TEXT_BASE - */ -#undef CONFIG_SKIP_RELOCATE_UBOOT - -/* * Environment setup */ @@ -238,4 +232,7 @@ */ #define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_SYS_SDRAM_BASE 0x80000000 +#define CONFIG_SYS_INIT_SP_ADDR (LOW_LEVEL_SRAM_STACK - CONFIG_SYS_GBL_DATA_SIZE) + #endif /* __CONFIG_H */ -- cgit v0.10.2 From 84b6631038a869a604adc9ca60c5f545bbf2650e Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Thu, 14 Oct 2010 16:53:27 -0400 Subject: OMAP3: SDRC: Introduce Numonyx DDR type Introduce Numonyx DDR timings and provide CONFIG_OMAP3_NUMONYX_DDR config options to allow for platform files to setup their timings. Signed-off-by: Enric Balletbo i Serra Acked-by: Steve Sakoman Tested-by: Steve Sakoman Signed-off-by: Sandeep Paulraj diff --git a/arch/arm/include/asm/arch-omap3/mem.h b/arch/arm/include/asm/arch-omap3/mem.h index a78cf9f..f165949 100644 --- a/arch/arm/include/asm/arch-omap3/mem.h +++ b/arch/arm/include/asm/arch-omap3/mem.h @@ -128,6 +128,45 @@ enum { (MICRON_XSR_165 << 0) | (MICRON_TXP_165 << 8) | \ (MICRON_TWTR_165 << 16)) +/* + * NUMONYX part of IGEP v2 (165MHz optimized) 6.06ns + * ACTIMA + * TDAL = Twr/Tck + Trp/tck = 15/6 + 18/6 = 2.5 + 3 = 5.5 -> 6 + * TDPL (Twr) = 15/6 = 2.5 -> 3 + * TRRD = 12/6 = 2 + * TRCD = 22.5/6 = 3.75 -> 4 + * TRP = 18/6 = 3 + * TRAS = 42/6 = 7 + * TRC = 60/6 = 10 + * TRFC = 140/6 = 23.3 -> 24 + * ACTIMB + * TWTR = 2 + * TCKE = 2 + * TXSR = 200/6 = 33.3 -> 34 + * TXP = 1.0 + 1.1 = 2.1 -> 3 + */ +#define NUMONYX_TDAL_165 6 +#define NUMONYX_TDPL_165 3 +#define NUMONYX_TRRD_165 2 +#define NUMONYX_TRCD_165 4 +#define NUMONYX_TRP_165 3 +#define NUMONYX_TRAS_165 7 +#define NUMONYX_TRC_165 10 +#define NUMONYX_TRFC_165 24 +#define NUMONYX_V_ACTIMA_165 ((NUMONYX_TRFC_165 << 27) | \ + (NUMONYX_TRC_165 << 22) | (NUMONYX_TRAS_165 << 18) | \ + (NUMONYX_TRP_165 << 15) | (NUMONYX_TRCD_165 << 12) | \ + (NUMONYX_TRRD_165 << 9) | (NUMONYX_TDPL_165 << 6) | \ + (NUMONYX_TDAL_165)) + +#define NUMONYX_TWTR_165 2 +#define NUMONYX_TCKE_165 2 +#define NUMONYX_TXP_165 3 +#define NUMONYX_XSR_165 34 +#define NUMONYX_V_ACTIMB_165 ((NUMONYX_TCKE_165 << 12) | \ + (NUMONYX_XSR_165 << 0) | (NUMONYX_TXP_165 << 8) | \ + (NUMONYX_TWTR_165 << 16)) + #ifdef CONFIG_OMAP3_INFINEON_DDR #define V_ACTIMA_165 INFINEON_V_ACTIMA_165 #define V_ACTIMB_165 INFINEON_V_ACTIMB_165 @@ -136,6 +175,10 @@ enum { #define V_ACTIMA_165 MICRON_V_ACTIMA_165 #define V_ACTIMB_165 MICRON_V_ACTIMB_165 #endif +#ifdef CONFIG_OMAP3_NUMONYX_DDR +#define V_ACTIMA_165 NUMONYX_V_ACTIMA_165 +#define V_ACTIMB_165 NUMONYX_V_ACTIMB_165 +#endif #if !defined(V_ACTIMA_165) || !defined(V_ACTIMB_165) #error "Please choose the right DDR type in config header" -- cgit v0.10.2 From 8a3f6bb6fb0d620dbad035e3d977a0b064f408d5 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Thu, 14 Oct 2010 16:54:59 -0400 Subject: OMAP3: Add support for the IGEP v2 board. The IGEP v2 board is a low-cost, fan-less and industrial temperature range single board computer that unleashes laptop-like performance and expandability without the bulk, expense, or noise of typical desktop machines. Its architecture shares much in common with other OMAP3 boards. Signed-off-by: Enric Balletbo i Serra Acked-by: Steve Sakoman Tested-by: Steve Sakoman Signed-off-by: Sandeep Paulraj diff --git a/MAINTAINERS b/MAINTAINERS index aabd871..331377e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -827,6 +827,10 @@ Alex Z lart SA1100 dnp1110 SA1110 +Enric Balletbo i Serra + + igep0020 ARM ARMV7 (OMAP3xx SoC) + ------------------------------------------------------------------------- Unknown / orphaned boards: diff --git a/MAKEALL b/MAKEALL index abceccd..2af9a24 100755 --- a/MAKEALL +++ b/MAKEALL @@ -491,6 +491,7 @@ LIST_ARMV7=" \ am3517_evm \ ca9x4_ct_vxp \ devkit8000 \ + igep0020 \ mx51evk \ omap3_beagle \ omap3_overo \ diff --git a/board/isee/igep0020/Makefile b/board/isee/igep0020/Makefile new file mode 100644 index 0000000..2f11879 --- /dev/null +++ b/board/isee/igep0020/Makefile @@ -0,0 +1,49 @@ +# +# (C) Copyright 2000, 2001, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS := igep0020.o + +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +clean: + rm -f $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/isee/igep0020/config.mk b/board/isee/igep0020/config.mk new file mode 100644 index 0000000..b8812f9 --- /dev/null +++ b/board/isee/igep0020/config.mk @@ -0,0 +1,33 @@ +# +# (C) Copyright 2009 +# ISEE 2007 SL, +# +# IGEP0020 uses OMAP3 (ARM-CortexA8) cpu +# see http://www.ti.com/ for more information on Texas Instruments +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# Physical Address: +# 8000'0000 (bank0) +# A000/0000 (bank1) +# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 +# (mem base + reserved) + +# For use with external or internal boots. +TEXT_BASE = 0x80008000 diff --git a/board/isee/igep0020/igep0020.c b/board/isee/igep0020/igep0020.c new file mode 100644 index 0000000..3f7eda1 --- /dev/null +++ b/board/isee/igep0020/igep0020.c @@ -0,0 +1,129 @@ +/* + * (C) Copyright 2010 + * ISEE 2007 SL, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "igep0020.h" + +/* GPMC definitions for LAN9221 chips */ +static const u32 gpmc_lan_config[] = { + NET_LAN9221_GPMC_CONFIG1, + NET_LAN9221_GPMC_CONFIG2, + NET_LAN9221_GPMC_CONFIG3, + NET_LAN9221_GPMC_CONFIG4, + NET_LAN9221_GPMC_CONFIG5, + NET_LAN9221_GPMC_CONFIG6, +}; + +/* + * Routine: board_init + * Description: Early hardware init. + */ +int board_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + gpmc_init(); /* in SRAM or SDRAM, finish GPMC */ + /* board id for Linux */ + gd->bd->bi_arch_number = MACH_TYPE_IGEP0020; + /* boot param addr */ + gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100); + + return 0; +} + +/* + * Routine: setup_net_chip + * Description: Setting up the configuration GPMC registers specific to the + * Ethernet hardware. + */ +#if defined(CONFIG_CMD_NET) +static void setup_net_chip(void) +{ + struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE; + + enable_gpmc_cs_config(gpmc_lan_config, &gpmc_cfg->cs[5], 0x2C000000, + GPMC_SIZE_16M); + + /* Enable off mode for NWE in PADCONF_GPMC_NWE register */ + writew(readw(&ctrl_base->gpmc_nwe) | 0x0E00, &ctrl_base->gpmc_nwe); + /* Enable off mode for NOE in PADCONF_GPMC_NADV_ALE register */ + writew(readw(&ctrl_base->gpmc_noe) | 0x0E00, &ctrl_base->gpmc_noe); + /* Enable off mode for ALE in PADCONF_GPMC_NADV_ALE register */ + writew(readw(&ctrl_base->gpmc_nadv_ale) | 0x0E00, + &ctrl_base->gpmc_nadv_ale); + + /* Make GPIO 64 as output pin and send a magic pulse through it */ + if (!omap_request_gpio(64)) { + omap_set_gpio_direction(64, 0); + omap_set_gpio_dataout(64, 1); + udelay(1); + omap_set_gpio_dataout(64, 0); + udelay(1); + omap_set_gpio_dataout(64, 1); + } +} +#endif + +/* + * Routine: misc_init_r + * Description: Configure board specific parts + */ +int misc_init_r(void) +{ + twl4030_power_init(); + +#if defined(CONFIG_CMD_NET) + setup_net_chip(); +#endif + + dieid_num_r(); + + return 0; +} + +/* + * Routine: set_muxconf_regs + * Description: Setting up the configuration Mux registers specific to the + * hardware. Many pins need to be moved from protect to primary + * mode. + */ +void set_muxconf_regs(void) +{ + MUX_DEFAULT(); +} + +int board_eth_init(bd_t *bis) +{ + int rc = 0; +#ifdef CONFIG_SMC911X + rc = smc911x_initialize(0, CONFIG_SMC911X_BASE); +#endif + return rc; +} diff --git a/board/isee/igep0020/igep0020.h b/board/isee/igep0020/igep0020.h new file mode 100644 index 0000000..c08d758 --- /dev/null +++ b/board/isee/igep0020/igep0020.h @@ -0,0 +1,156 @@ +/* + * (C) Copyright 2010 + * ISEE 2007 SL, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _IGEP0020_H_ +#define _IGEP0020_H_ + +const omap3_sysinfo sysinfo = { + DDR_STACKED, + "IGEP v2 board", + "ONENAND", +}; + +/* GPMC CS 5 connected to an SMSC LAN9221 ethernet controller */ +#define NET_LAN9221_GPMC_CONFIG1 0x00001000 +#define NET_LAN9221_GPMC_CONFIG2 0x00080701 +#define NET_LAN9221_GPMC_CONFIG3 0x00020201 +#define NET_LAN9221_GPMC_CONFIG4 0x08030703 +#define NET_LAN9221_GPMC_CONFIG5 0x00060908 +#define NET_LAN9221_GPMC_CONFIG6 0x87030000 +#define NET_LAN9221_GPMC_CONFIG7 0x00000f6c + +static void setup_net_chip(void); + +/* + * IEN - Input Enable + * IDIS - Input Disable + * PTD - Pull type Down + * PTU - Pull type Up + * DIS - Pull type selection is inactive + * EN - Pull type selection is active + * M0 - Mode 0 + * The commented string gives the final mux configuration for that pin + */ +#define MUX_DEFAULT()\ + MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)) /* SDRC_D0 */\ + MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)) /* SDRC_D1 */\ + MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)) /* SDRC_D2 */\ + MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)) /* SDRC_D3 */\ + MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)) /* SDRC_D4 */\ + MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)) /* SDRC_D5 */\ + MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)) /* SDRC_D6 */\ + MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)) /* SDRC_D7 */\ + MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)) /* SDRC_D8 */\ + MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)) /* SDRC_D9 */\ + MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)) /* SDRC_D10 */\ + MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)) /* SDRC_D11 */\ + MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)) /* SDRC_D12 */\ + MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)) /* SDRC_D13 */\ + MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)) /* SDRC_D14 */\ + MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)) /* SDRC_D15 */\ + MUX_VAL(CP(SDRC_D16), (IEN | PTD | DIS | M0)) /* SDRC_D16 */\ + MUX_VAL(CP(SDRC_D17), (IEN | PTD | DIS | M0)) /* SDRC_D17 */\ + MUX_VAL(CP(SDRC_D18), (IEN | PTD | DIS | M0)) /* SDRC_D18 */\ + MUX_VAL(CP(SDRC_D19), (IEN | PTD | DIS | M0)) /* SDRC_D19 */\ + MUX_VAL(CP(SDRC_D20), (IEN | PTD | DIS | M0)) /* SDRC_D20 */\ + MUX_VAL(CP(SDRC_D21), (IEN | PTD | DIS | M0)) /* SDRC_D21 */\ + MUX_VAL(CP(SDRC_D22), (IEN | PTD | DIS | M0)) /* SDRC_D22 */\ + MUX_VAL(CP(SDRC_D23), (IEN | PTD | DIS | M0)) /* SDRC_D23 */\ + MUX_VAL(CP(SDRC_D24), (IEN | PTD | DIS | M0)) /* SDRC_D24 */\ + MUX_VAL(CP(SDRC_D25), (IEN | PTD | DIS | M0)) /* SDRC_D25 */\ + MUX_VAL(CP(SDRC_D26), (IEN | PTD | DIS | M0)) /* SDRC_D26 */\ + MUX_VAL(CP(SDRC_D27), (IEN | PTD | DIS | M0)) /* SDRC_D27 */\ + MUX_VAL(CP(SDRC_D28), (IEN | PTD | DIS | M0)) /* SDRC_D28 */\ + MUX_VAL(CP(SDRC_D29), (IEN | PTD | DIS | M0)) /* SDRC_D29 */\ + MUX_VAL(CP(SDRC_D30), (IEN | PTD | DIS | M0)) /* SDRC_D30 */\ + MUX_VAL(CP(SDRC_D31), (IEN | PTD | DIS | M0)) /* SDRC_D31 */\ + MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)) /* SDRC_CLK */\ + MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)) /* SDRC_DQS0 */\ + MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)) /* SDRC_DQS1 */\ + MUX_VAL(CP(SDRC_DQS2), (IEN | PTD | DIS | M0)) /* SDRC_DQS2 */\ + MUX_VAL(CP(SDRC_DQS3), (IEN | PTD | DIS | M0)) /* SDRC_DQS3 */\ + MUX_VAL(CP(GPMC_A1), (IDIS | PTD | DIS | M0)) /* GPMC_A1 */\ + MUX_VAL(CP(GPMC_A2), (IDIS | PTD | DIS | M0)) /* GPMC_A2 */\ + MUX_VAL(CP(GPMC_A3), (IDIS | PTD | DIS | M0)) /* GPMC_A3 */\ + MUX_VAL(CP(GPMC_A4), (IDIS | PTD | DIS | M0)) /* GPMC_A4 */\ + MUX_VAL(CP(GPMC_A5), (IDIS | PTD | DIS | M0)) /* GPMC_A5 */\ + MUX_VAL(CP(GPMC_A6), (IDIS | PTD | DIS | M0)) /* GPMC_A6 */\ + MUX_VAL(CP(GPMC_A7), (IDIS | PTD | DIS | M0)) /* GPMC_A7 */\ + MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M0)) /* GPMC_A8 */\ + MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M0)) /* GPMC_A9 */\ + MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M0)) /* GPMC_A10 */\ + MUX_VAL(CP(GPMC_D0), (IEN | PTD | DIS | M0)) /* GPMC_D0 */\ + MUX_VAL(CP(GPMC_D1), (IEN | PTD | DIS | M0)) /* GPMC_D1 */\ + MUX_VAL(CP(GPMC_D2), (IEN | PTD | DIS | M0)) /* GPMC_D2 */\ + MUX_VAL(CP(GPMC_D3), (IEN | PTD | DIS | M0)) /* GPMC_D3 */\ + MUX_VAL(CP(GPMC_D4), (IEN | PTD | DIS | M0)) /* GPMC_D4 */\ + MUX_VAL(CP(GPMC_D5), (IEN | PTD | DIS | M0)) /* GPMC_D5 */\ + MUX_VAL(CP(GPMC_D6), (IEN | PTD | DIS | M0)) /* GPMC_D6 */\ + MUX_VAL(CP(GPMC_D7), (IEN | PTD | DIS | M0)) /* GPMC_D7 */\ + MUX_VAL(CP(GPMC_D8), (IEN | PTD | DIS | M0)) /* GPMC_D8 */\ + MUX_VAL(CP(GPMC_D9), (IEN | PTD | DIS | M0)) /* GPMC_D9 */\ + MUX_VAL(CP(GPMC_D10), (IEN | PTD | DIS | M0)) /* GPMC_D10 */\ + MUX_VAL(CP(GPMC_D11), (IEN | PTD | DIS | M0)) /* GPMC_D11 */\ + MUX_VAL(CP(GPMC_D12), (IEN | PTD | DIS | M0)) /* GPMC_D12 */\ + MUX_VAL(CP(GPMC_D13), (IEN | PTD | DIS | M0)) /* GPMC_D13 */\ + MUX_VAL(CP(GPMC_D14), (IEN | PTD | DIS | M0)) /* GPMC_D14 */\ + MUX_VAL(CP(GPMC_D15), (IEN | PTD | DIS | M0)) /* GPMC_D15 */\ + MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)) /* GPMC_nCS0 */\ + MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M0)) /* GPMC_nCS1 */\ + MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M0)) /* GPIO_nCS2 */\ + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN | M0)) /* GPIO_nCS3 */\ + MUX_VAL(CP(GPMC_NCS4), (IDIS | PTU | EN | M0)) /* GPMC_nCS4 */\ + MUX_VAL(CP(GPMC_NCS5), (IDIS | PTU | EN | M0)) /* GPMC_nCS5 */\ + MUX_VAL(CP(GPMC_NCS6), (IDIS | PTU | EN | M0)) /* GPMC_nCS6 */\ + MUX_VAL(CP(GPMC_NCS7), (IDIS | PTU | EN | M0)) /* GPMC_nCS7 */\ + MUX_VAL(CP(GPMC_CLK), (IDIS | PTD | DIS | M0)) /* GPMC_CLK */\ + MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)) /* GPMC_nADV_ALE */\ + MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)) /* GPMC_nOE */\ + MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)) /* GPMC_nWE */\ + MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTD | DIS | M0)) /* GPMC_nBE0_CLE */\ + MUX_VAL(CP(GPMC_NBE1), (IEN | PTD | DIS | M0)) /* GPMC_nBE1 */\ + MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0)) /* GPMC_nWP */\ + MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)) /* GPMC_WAIT0 */\ + MUX_VAL(CP(GPMC_WAIT2), (IEN | PTU | DIS | M4)) /* GPIO_64-ETH_NRST */\ + MUX_VAL(CP(MMC1_CLK), (IDIS | PTU | EN | M0)) /* MMC1_CLK */\ + MUX_VAL(CP(MMC1_CMD), (IEN | PTU | EN | M0)) /* MMC1_CMD */\ + MUX_VAL(CP(MMC1_DAT0), (IEN | PTU | EN | M0)) /* MMC1_DAT0 */\ + MUX_VAL(CP(MMC1_DAT1), (IEN | PTU | EN | M0)) /* MMC1_DAT1 */\ + MUX_VAL(CP(MMC1_DAT2), (IEN | PTU | EN | M0)) /* MMC1_DAT2 */\ + MUX_VAL(CP(MMC1_DAT3), (IEN | PTU | EN | M0)) /* MMC1_DAT3 */\ + MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0)) /* UART3_TX */\ + MUX_VAL(CP(UART3_RX_IRRX), (IEN | PTD | DIS | M0)) /* UART3_RX */\ + MUX_VAL(CP(I2C1_SCL), (IEN | PTU | EN | M0)) /* I2C1_SCL */\ + MUX_VAL(CP(I2C1_SDA), (IEN | PTU | EN | M0)) /* I2C1_SDA */\ + MUX_VAL(CP(I2C4_SCL), (IEN | PTU | EN | M0)) /* I2C4_SCL */\ + MUX_VAL(CP(I2C4_SDA), (IEN | PTU | EN | M0)) /* I2C4_SDA */\ + MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)) /* SYS_32K */\ + MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M4)) /* GPIO_2 */\ + MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M4)) /* GPIO_3 */\ + MUX_VAL(CP(SYS_BOOT2), (IEN | PTD | DIS | M4)) /* GPIO_4 */\ + MUX_VAL(CP(SYS_BOOT3), (IEN | PTD | DIS | M4)) /* GPIO_5 */\ + MUX_VAL(CP(SYS_BOOT4), (IEN | PTD | DIS | M4)) /* GPIO_6 */\ + MUX_VAL(CP(SYS_BOOT5), (IEN | PTD | DIS | M4)) /* GPIO_7 */\ + MUX_VAL(CP(SYS_BOOT6), (IEN | PTD | DIS | M4)) /* GPIO_8 */\ + MUX_VAL(CP(SDRC_CKE0), (IDIS | PTU | EN | M0)) /* SDRC_CKE0 */\ + MUX_VAL(CP(SDRC_CKE1), (IDIS | PTU | EN | M0)) /* SDRC_CKE1 */ +#endif diff --git a/boards.cfg b/boards.cfg index 132d178..e83197d 100644 --- a/boards.cfg +++ b/boards.cfg @@ -265,6 +265,7 @@ omap4_panda arm armv7 panda ti omap4 omap4_sdp4430 arm armv7 sdp4430 ti omap4 am3517_evm arm armv7 am3517evm logicpd omap3 devkit8000 arm armv7 devkit8000 timll omap3 +igep0020 arm armv7 igep0020 isee omap3 s5p_goni arm armv7 goni samsung s5pc1xx smdkc100 arm armv7 smdkc100 samsung s5pc1xx ixdpg425 arm ixp diff --git a/include/configs/igep0020.h b/include/configs/igep0020.h new file mode 100644 index 0000000..34e8a57 --- /dev/null +++ b/include/configs/igep0020.h @@ -0,0 +1,228 @@ +/* + * (C) Copyright 2010 + * ISEE 2007 SL, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H +#include + +/* + * High Level Configuration Options + */ +#define CONFIG_ARMV7 1 /* This is an ARM V7 CPU core */ +#define CONFIG_OMAP 1 /* in a TI OMAP core */ +#define CONFIG_OMAP34XX 1 /* which is a 34XX */ +#define CONFIG_OMAP3430 1 /* which is in a 3430 */ +#define CONFIG_OMAP3_IGEP0020 1 /* working with IGEP0020 */ + +#define CONFIG_SDRC /* The chip has SDRC controller */ + +#include +#include + +/* + * Display CPU and Board information + */ +#define CONFIG_DISPLAY_CPUINFO 1 +#define CONFIG_DISPLAY_BOARDINFO 1 + +/* Clock Defines */ +#define V_OSCK 26000000 /* Clock output from T2 */ +#define V_SCLK (V_OSCK >> 1) + +#define CONFIG_MISC_INIT_R + +#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 +#define CONFIG_REVISION_TAG 1 + +/* + * NS16550 Configuration + */ + +#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */ + +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE (-4) +#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK + +/* select serial console configuration */ +#define CONFIG_CONS_INDEX 3 +#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3 +#define CONFIG_SERIAL3 3 + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, 115200} +#define CONFIG_MMC 1 +#define CONFIG_OMAP3_MMC 1 +#define CONFIG_DOS_PARTITION 1 + +/* DDR */ +#define CONFIG_OMAP3_NUMONYX_DDR 1 + +/* USB */ +#define CONFIG_MUSB_UDC 1 +#define CONFIG_USB_OMAP3 1 +#define CONFIG_TWL4030_USB 1 + +/* USB device configuration */ +#define CONFIG_USB_DEVICE 1 +#define CONFIG_USB_TTY 1 +#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1 + +/* Change these to suit your needs */ +#define CONFIG_USBD_VENDORID 0x0451 +#define CONFIG_USBD_PRODUCTID 0x5678 +#define CONFIG_USBD_MANUFACTURER "Texas Instruments" +#define CONFIG_USBD_PRODUCT_NAME "IGEP" + +/* commands to include */ +#include + +#define CONFIG_CMD_CACHE +#define CONFIG_CMD_EXT2 /* EXT2 Support */ +#define CONFIG_CMD_FAT /* FAT support */ +#define CONFIG_CMD_I2C /* I2C serial bus support */ +#define CONFIG_CMD_MMC /* MMC support */ +#define CONFIG_CMD_ONENAND /* ONENAND support */ +#define CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */ +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_PING +#define CONFIG_CMD_NFS /* NFS support */ +#define CONFIG_CMD_MTDPARTS /* Enable MTD parts commands */ +#define CONFIG_MTD_DEVICE + +#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */ +#undef CONFIG_CMD_IMLS /* List all found images */ + +#define CONFIG_SYS_NO_FLASH +#define CONFIG_HARD_I2C 1 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 1 +#define CONFIG_SYS_I2C_BUS 0 +#define CONFIG_SYS_I2C_BUS_SELECT 1 +#define CONFIG_DRIVER_OMAP34XX_I2C 1 + +/* + * TWL4030 + */ +#define CONFIG_TWL4030_POWER 1 + +/* Environment information */ +#define CONFIG_BOOTCOMMAND \ + "mmc init 0 ; fatload mmc 0 0x80000000 setup.ini ; source \0" + +#define CONFIG_BOOTDELAY 3 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "usbtty=cdc_acm\0" + +#define CONFIG_AUTO_COMPLETE 1 + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_SYS_PROMPT "U-Boot # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +/* Print Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE) + +#define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0) /* memtest */ + /* works on */ +#define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + \ + 0x01F00000) /* 31MB */ + +#define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0) /* default */ + /* load address */ + +#define CONFIG_SYS_MONITOR_LEN (256 << 10) + +/* + * OMAP3 has 12 GP timers, they can be driven by the system clock + * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). + * This rate is divided by a local divisor. + */ +#define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) +#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */ +#define CONFIG_SYS_HZ 1000 + +/* + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128 << 10) /* regular stack 128 KiB */ + +/* + * Physical Memory Map + * + */ +#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */ +#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0 +#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 meg */ +#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1 + +/* SDRAM Bank Allocation method */ +#define SDRC_R_B_C 1 + +/* + * FLASH and environment organization + */ + +#define PISMO1_ONEN_SIZE GPMC_SIZE_128M /* Configure the PISMO */ + +#define CONFIG_SYS_ONENAND_BASE ONENAND_MAP + +#define ONENAND_ENV_OFFSET 0x260000 /* environment starts here */ + +#define CONFIG_ENV_IS_IN_ONENAND 1 +#define CONFIG_ENV_SIZE (512 << 10) /* Total Size Environment */ +#define CONFIG_ENV_ADDR ONENAND_ENV_OFFSET + +/* + * Size of malloc() pool + */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (128 << 10)) +#define CONFIG_SYS_GBL_DATA_SIZE 128 /* bytes for initial data */ + +/* + * SMSC911x Ethernet + */ +#if defined(CONFIG_CMD_NET) +#define CONFIG_NET_MULTI +#define CONFIG_SMC911X +#define CONFIG_SMC911X_32_BIT +#define CONFIG_SMC911X_BASE 0x2C000000 +#endif /* (CONFIG_CMD_NET) */ + +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 +#define CONFIG_SYS_INIT_SP_ADDR (LOW_LEVEL_SRAM_STACK - CONFIG_SYS_GBL_DATA_SIZE) + +#endif /* __CONFIG_H */ -- cgit v0.10.2 From 1a832dc4f8cd4cf899117ecab4821bdb9a4005bc Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Thu, 14 Oct 2010 16:57:39 -0400 Subject: OMAP3: Add support for the OMAP3 IGEP module. The IGEP module is a low-power, high performance production-ready system-on-module (SOM) based on TI's OMAP3 family.The IGEP module solution based upon TI OMAP3 provides a low-power/low-cost platform for a variety of consumer/industrial/medical devices. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Sandeep Paulraj diff --git a/MAINTAINERS b/MAINTAINERS index 331377e..5b526c0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -830,6 +830,7 @@ Alex Z Enric Balletbo i Serra igep0020 ARM ARMV7 (OMAP3xx SoC) + igep0030 ARM ARMV7 (OMAP3xx SoC) ------------------------------------------------------------------------- diff --git a/MAKEALL b/MAKEALL index 2af9a24..133810c 100755 --- a/MAKEALL +++ b/MAKEALL @@ -492,6 +492,7 @@ LIST_ARMV7=" \ ca9x4_ct_vxp \ devkit8000 \ igep0020 \ + igep0030 \ mx51evk \ omap3_beagle \ omap3_overo \ diff --git a/board/isee/igep0030/Makefile b/board/isee/igep0030/Makefile new file mode 100644 index 0000000..cfc0411 --- /dev/null +++ b/board/isee/igep0030/Makefile @@ -0,0 +1,49 @@ +# +# (C) Copyright 2000, 2001, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS := igep0030.o + +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +clean: + rm -f $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/isee/igep0030/config.mk b/board/isee/igep0030/config.mk new file mode 100644 index 0000000..35865e0 --- /dev/null +++ b/board/isee/igep0030/config.mk @@ -0,0 +1,34 @@ +# +# (C) Copyright 2009 +# ISEE 2007 SL, +# +# IGEP0030 uses OMAP3 (ARM-CortexA8) cpu +# see http://www.ti.com/ for more information on Texas Instruments +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# Physical Address: +# 8000'0000 (bank0) +# A000/0000 (bank1) +# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 +# (mem base + reserved) + +# For use with external or internal boots. +TEXT_BASE = 0x80008000 + diff --git a/board/isee/igep0030/igep0030.c b/board/isee/igep0030/igep0030.c new file mode 100644 index 0000000..9244259 --- /dev/null +++ b/board/isee/igep0030/igep0030.c @@ -0,0 +1,71 @@ +/* + * (C) Copyright 2010 + * ISEE 2007 SL, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include "igep0030.h" + +/* + * Routine: board_init + * Description: Early hardware init. + */ +int board_init(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + gpmc_init(); /* in SRAM or SDRAM, finish GPMC */ + /* board id for Linux */ + gd->bd->bi_arch_number = MACH_TYPE_IGEP0030; + /* boot param addr */ + gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100); + + return 0; +} + +/* + * Routine: misc_init_r + * Description: Configure board specific parts + */ +int misc_init_r(void) +{ + twl4030_power_init(); + + dieid_num_r(); + + return 0; +} + +/* + * Routine: set_muxconf_regs + * Description: Setting up the configuration Mux registers specific to the + * hardware. Many pins need to be moved from protect to primary + * mode. + */ +void set_muxconf_regs(void) +{ + MUX_DEFAULT(); +} diff --git a/board/isee/igep0030/igep0030.h b/board/isee/igep0030/igep0030.h new file mode 100644 index 0000000..b7ce5aa --- /dev/null +++ b/board/isee/igep0030/igep0030.h @@ -0,0 +1,147 @@ +/* + * (C) Copyright 2010 + * ISEE 2007 SL, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _IGEP0030_H_ +#define _IGEP0030_H_ + +const omap3_sysinfo sysinfo = { + DDR_STACKED, + "OMAP3 IGEP module", + "ONENAND", +}; + +/* + * IEN - Input Enable + * IDIS - Input Disable + * PTD - Pull type Down + * PTU - Pull type Up + * DIS - Pull type selection is inactive + * EN - Pull type selection is active + * M0 - Mode 0 + * The commented string gives the final mux configuration for that pin + */ + +#define MUX_DEFAULT()\ + MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)) /* SDRC_D0 */\ + MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)) /* SDRC_D1 */\ + MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)) /* SDRC_D2 */\ + MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)) /* SDRC_D3 */\ + MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)) /* SDRC_D4 */\ + MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)) /* SDRC_D5 */\ + MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)) /* SDRC_D6 */\ + MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)) /* SDRC_D7 */\ + MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)) /* SDRC_D8 */\ + MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)) /* SDRC_D9 */\ + MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)) /* SDRC_D10 */\ + MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)) /* SDRC_D11 */\ + MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)) /* SDRC_D12 */\ + MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)) /* SDRC_D13 */\ + MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)) /* SDRC_D14 */\ + MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)) /* SDRC_D15 */\ + MUX_VAL(CP(SDRC_D16), (IEN | PTD | DIS | M0)) /* SDRC_D16 */\ + MUX_VAL(CP(SDRC_D17), (IEN | PTD | DIS | M0)) /* SDRC_D17 */\ + MUX_VAL(CP(SDRC_D18), (IEN | PTD | DIS | M0)) /* SDRC_D18 */\ + MUX_VAL(CP(SDRC_D19), (IEN | PTD | DIS | M0)) /* SDRC_D19 */\ + MUX_VAL(CP(SDRC_D20), (IEN | PTD | DIS | M0)) /* SDRC_D20 */\ + MUX_VAL(CP(SDRC_D21), (IEN | PTD | DIS | M0)) /* SDRC_D21 */\ + MUX_VAL(CP(SDRC_D22), (IEN | PTD | DIS | M0)) /* SDRC_D22 */\ + MUX_VAL(CP(SDRC_D23), (IEN | PTD | DIS | M0)) /* SDRC_D23 */\ + MUX_VAL(CP(SDRC_D24), (IEN | PTD | DIS | M0)) /* SDRC_D24 */\ + MUX_VAL(CP(SDRC_D25), (IEN | PTD | DIS | M0)) /* SDRC_D25 */\ + MUX_VAL(CP(SDRC_D26), (IEN | PTD | DIS | M0)) /* SDRC_D26 */\ + MUX_VAL(CP(SDRC_D27), (IEN | PTD | DIS | M0)) /* SDRC_D27 */\ + MUX_VAL(CP(SDRC_D28), (IEN | PTD | DIS | M0)) /* SDRC_D28 */\ + MUX_VAL(CP(SDRC_D29), (IEN | PTD | DIS | M0)) /* SDRC_D29 */\ + MUX_VAL(CP(SDRC_D30), (IEN | PTD | DIS | M0)) /* SDRC_D30 */\ + MUX_VAL(CP(SDRC_D31), (IEN | PTD | DIS | M0)) /* SDRC_D31 */\ + MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)) /* SDRC_CLK */\ + MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)) /* SDRC_DQS0 */\ + MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)) /* SDRC_DQS1 */\ + MUX_VAL(CP(SDRC_DQS2), (IEN | PTD | DIS | M0)) /* SDRC_DQS2 */\ + MUX_VAL(CP(SDRC_DQS3), (IEN | PTD | DIS | M0)) /* SDRC_DQS3 */\ + MUX_VAL(CP(GPMC_A1), (IDIS | PTD | DIS | M0)) /* GPMC_A1 */\ + MUX_VAL(CP(GPMC_A2), (IDIS | PTD | DIS | M0)) /* GPMC_A2 */\ + MUX_VAL(CP(GPMC_A3), (IDIS | PTD | DIS | M0)) /* GPMC_A3 */\ + MUX_VAL(CP(GPMC_A4), (IDIS | PTD | DIS | M0)) /* GPMC_A4 */\ + MUX_VAL(CP(GPMC_A5), (IDIS | PTD | DIS | M0)) /* GPMC_A5 */\ + MUX_VAL(CP(GPMC_A6), (IDIS | PTD | DIS | M0)) /* GPMC_A6 */\ + MUX_VAL(CP(GPMC_A7), (IDIS | PTD | DIS | M0)) /* GPMC_A7 */\ + MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M0)) /* GPMC_A8 */\ + MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M0)) /* GPMC_A9 */\ + MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M0)) /* GPMC_A10 */\ + MUX_VAL(CP(GPMC_D0), (IEN | PTD | DIS | M0)) /* GPMC_D0 */\ + MUX_VAL(CP(GPMC_D1), (IEN | PTD | DIS | M0)) /* GPMC_D1 */\ + MUX_VAL(CP(GPMC_D2), (IEN | PTD | DIS | M0)) /* GPMC_D2 */\ + MUX_VAL(CP(GPMC_D3), (IEN | PTD | DIS | M0)) /* GPMC_D3 */\ + MUX_VAL(CP(GPMC_D4), (IEN | PTD | DIS | M0)) /* GPMC_D4 */\ + MUX_VAL(CP(GPMC_D5), (IEN | PTD | DIS | M0)) /* GPMC_D5 */\ + MUX_VAL(CP(GPMC_D6), (IEN | PTD | DIS | M0)) /* GPMC_D6 */\ + MUX_VAL(CP(GPMC_D7), (IEN | PTD | DIS | M0)) /* GPMC_D7 */\ + MUX_VAL(CP(GPMC_D8), (IEN | PTD | DIS | M0)) /* GPMC_D8 */\ + MUX_VAL(CP(GPMC_D9), (IEN | PTD | DIS | M0)) /* GPMC_D9 */\ + MUX_VAL(CP(GPMC_D10), (IEN | PTD | DIS | M0)) /* GPMC_D10 */\ + MUX_VAL(CP(GPMC_D11), (IEN | PTD | DIS | M0)) /* GPMC_D11 */\ + MUX_VAL(CP(GPMC_D12), (IEN | PTD | DIS | M0)) /* GPMC_D12 */\ + MUX_VAL(CP(GPMC_D13), (IEN | PTD | DIS | M0)) /* GPMC_D13 */\ + MUX_VAL(CP(GPMC_D14), (IEN | PTD | DIS | M0)) /* GPMC_D14 */\ + MUX_VAL(CP(GPMC_D15), (IEN | PTD | DIS | M0)) /* GPMC_D15 */\ + MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)) /* GPMC_nCS0 */\ + MUX_VAL(CP(GPMC_NCS1), (IDIS | PTU | EN | M0)) /* GPMC_nCS1 */\ + MUX_VAL(CP(GPMC_NCS2), (IDIS | PTU | EN | M0)) /* GPIO_nCS2 */\ + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | EN | M0)) /* GPIO_nCS3 */\ + MUX_VAL(CP(GPMC_NCS4), (IDIS | PTU | EN | M0)) /* GPMC_nCS4 */\ + MUX_VAL(CP(GPMC_NCS5), (IDIS | PTU | EN | M0)) /* GPMC_nCS5 */\ + MUX_VAL(CP(GPMC_NCS6), (IDIS | PTU | EN | M0)) /* GPMC_nCS6 */\ + MUX_VAL(CP(GPMC_NCS7), (IDIS | PTU | EN | M0)) /* GPMC_nCS7 */\ + MUX_VAL(CP(GPMC_CLK), (IDIS | PTD | DIS | M0)) /* GPMC_CLK */\ + MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)) /* GPMC_nADV_ALE*/\ + MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)) /* GPMC_nOE */\ + MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)) /* GPMC_nWE */\ + MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTD | DIS | M0)) /* GPMC_nBE0_CLE*/\ + MUX_VAL(CP(GPMC_NBE1), (IEN | PTD | DIS | M0)) /* GPMC_nBE1 */\ + MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0)) /* GPMC_nWP */\ + MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)) /* GPMC_WAIT0 */\ + MUX_VAL(CP(MMC1_CLK), (IDIS | PTU | EN | M0)) /* MMC1_CLK */\ + MUX_VAL(CP(MMC1_CMD), (IEN | PTU | EN | M0)) /* MMC1_CMD */\ + MUX_VAL(CP(MMC1_DAT0), (IEN | PTU | EN | M0)) /* MMC1_DAT0 */\ + MUX_VAL(CP(MMC1_DAT1), (IEN | PTU | EN | M0)) /* MMC1_DAT1 */\ + MUX_VAL(CP(MMC1_DAT2), (IEN | PTU | EN | M0)) /* MMC1_DAT2 */\ + MUX_VAL(CP(MMC1_DAT3), (IEN | PTU | EN | M0)) /* MMC1_DAT3 */\ + MUX_VAL(CP(UART1_TX), (IDIS | PTD | DIS | M0)) /* UART1_TX */\ + MUX_VAL(CP(UART1_RX), (IEN | PTD | DIS | M0)) /* UART1_RX */\ + MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0)) /* UART3_TX */\ + MUX_VAL(CP(UART3_RX_IRRX), (IEN | PTD | DIS | M0)) /* UART3_RX */\ + MUX_VAL(CP(I2C1_SCL), (IEN | PTU | EN | M0)) /* I2C1_SCL */\ + MUX_VAL(CP(I2C1_SDA), (IEN | PTU | EN | M0)) /* I2C1_SDA */\ + MUX_VAL(CP(I2C4_SCL), (IEN | PTU | EN | M0)) /* I2C4_SCL */\ + MUX_VAL(CP(I2C4_SDA), (IEN | PTU | EN | M0)) /* I2C4_SDA */\ + MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)) /* SYS_32K */\ + MUX_VAL(CP(SYS_BOOT0), (IEN | PTD | DIS | M4)) /* GPIO_2 */\ + MUX_VAL(CP(SYS_BOOT1), (IEN | PTD | DIS | M4)) /* GPIO_3 */\ + MUX_VAL(CP(SYS_BOOT2), (IEN | PTD | DIS | M4)) /* GPIO_4 */\ + MUX_VAL(CP(SYS_BOOT3), (IEN | PTD | DIS | M4)) /* GPIO_5 */\ + MUX_VAL(CP(SYS_BOOT4), (IEN | PTD | DIS | M4)) /* GPIO_6 */\ + MUX_VAL(CP(SYS_BOOT5), (IEN | PTD | DIS | M4)) /* GPIO_7 */\ + MUX_VAL(CP(SYS_BOOT6), (IEN | PTD | DIS | M4)) /* GPIO_8 */\ + MUX_VAL(CP(SDRC_CKE0), (IDIS | PTU | EN | M0)) /* SDRC_CKE0 */\ + MUX_VAL(CP(SDRC_CKE1), (IDIS | PTU | EN | M0)) /* SDRC_CKE1 */ +#endif diff --git a/boards.cfg b/boards.cfg index e83197d..4c73680 100644 --- a/boards.cfg +++ b/boards.cfg @@ -266,6 +266,7 @@ omap4_sdp4430 arm armv7 sdp4430 ti omap4 am3517_evm arm armv7 am3517evm logicpd omap3 devkit8000 arm armv7 devkit8000 timll omap3 igep0020 arm armv7 igep0020 isee omap3 +igep0030 arm armv7 igep0030 isee omap3 s5p_goni arm armv7 goni samsung s5pc1xx smdkc100 arm armv7 smdkc100 samsung s5pc1xx ixdpg425 arm ixp diff --git a/include/configs/igep0030.h b/include/configs/igep0030.h new file mode 100644 index 0000000..5e2e0ed --- /dev/null +++ b/include/configs/igep0030.h @@ -0,0 +1,215 @@ +/* + * (C) Copyright 2010 + * ISEE 2007 SL, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __CONFIG_H +#define __CONFIG_H +#include + +/* + * High Level Configuration Options + */ +#define CONFIG_ARMV7 1 /* This is an ARM V7 CPU core */ +#define CONFIG_OMAP 1 /* in a TI OMAP core */ +#define CONFIG_OMAP34XX 1 /* which is a 34XX */ +#define CONFIG_OMAP3430 1 /* which is in a 3430 */ +#define CONFIG_OMAP3_IGEP0030 1 /* working with IGEP0030 */ + +#define CONFIG_SDRC /* The chip has SDRC controller */ + +#include +#include + +/* + * Display CPU and Board information + */ +#define CONFIG_DISPLAY_CPUINFO 1 +#define CONFIG_DISPLAY_BOARDINFO 1 + +/* Clock Defines */ +#define V_OSCK 26000000 /* Clock output from T2 */ +#define V_SCLK (V_OSCK >> 1) + +#define CONFIG_MISC_INIT_R + +#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG 1 +#define CONFIG_REVISION_TAG 1 + +/* + * NS16550 Configuration + */ + +#define V_NS16550_CLK 48000000 /* 48MHz (APLL96/2) */ + +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE (-4) +#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK + +/* select serial console configuration */ +#define CONFIG_CONS_INDEX 3 +#define CONFIG_SYS_NS16550_COM3 OMAP34XX_UART3 +#define CONFIG_SERIAL3 3 + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, 115200} +#define CONFIG_MMC 1 +#define CONFIG_OMAP3_MMC 1 +#define CONFIG_DOS_PARTITION 1 + +/* DDR */ +#define CONFIG_OMAP3_NUMONYX_DDR 1 + +/* USB */ +#define CONFIG_MUSB_UDC 1 +#define CONFIG_USB_OMAP3 1 +#define CONFIG_TWL4030_USB 1 + +/* USB device configuration */ +#define CONFIG_USB_DEVICE 1 +#define CONFIG_USB_TTY 1 +#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1 + +/* Change these to suit your needs */ +#define CONFIG_USBD_VENDORID 0x0451 +#define CONFIG_USBD_PRODUCTID 0x5678 +#define CONFIG_USBD_MANUFACTURER "Texas Instruments" +#define CONFIG_USBD_PRODUCT_NAME "IGEP" + +/* commands to include */ +#include + +#define CONFIG_CMD_CACHE +#define CONFIG_CMD_EXT2 /* EXT2 Support */ +#define CONFIG_CMD_FAT /* FAT support */ +#define CONFIG_CMD_I2C /* I2C serial bus support */ +#define CONFIG_CMD_MMC /* MMC support */ +#define CONFIG_CMD_ONENAND /* ONENAND support */ +#define CONFIG_CMD_MTDPARTS /* Enable MTD parts commands */ +#define CONFIG_MTD_DEVICE + +#undef CONFIG_CMD_NET /* bootp, tftpboot, rarpboot */ +#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */ +#undef CONFIG_CMD_IMLS /* List all found images */ + +#define CONFIG_SYS_NO_FLASH +#define CONFIG_HARD_I2C 1 +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 1 +#define CONFIG_SYS_I2C_BUS 0 +#define CONFIG_SYS_I2C_BUS_SELECT 1 +#define CONFIG_DRIVER_OMAP34XX_I2C 1 + +/* + * TWL4030 + */ +#define CONFIG_TWL4030_POWER 1 + +/* Environment information */ +#define CONFIG_BOOTCOMMAND \ + "mmc init 0 ; fatload mmc 0 0x80000000 setup.ini ; source \0" + +#define CONFIG_BOOTDELAY 3 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "usbtty=cdc_acm\0" + +#define CONFIG_AUTO_COMPLETE 1 + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_SYS_PROMPT "U-Boot # " +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +/* Print Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE) + +#define CONFIG_SYS_MEMTEST_START (OMAP34XX_SDRC_CS0) /* memtest */ + /* works on */ +#define CONFIG_SYS_MEMTEST_END (OMAP34XX_SDRC_CS0 + \ + 0x01F00000) /* 31MB */ + +#define CONFIG_SYS_LOAD_ADDR (OMAP34XX_SDRC_CS0) /* default */ + /* load address */ + +#define CONFIG_SYS_MONITOR_LEN (256 << 10) + +/* + * OMAP3 has 12 GP timers, they can be driven by the system clock + * (12/13/16.8/19.2/38.4MHz) or by 32KHz clock. We use 13MHz (V_SCLK). + * This rate is divided by a local divisor. + */ +#define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2) +#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */ +#define CONFIG_SYS_HZ 1000 + +/* + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (128 << 10) /* regular stack 128 KiB */ + +/* + * Physical Memory Map + * + */ +#define CONFIG_NR_DRAM_BANKS 2 /* CS1 may or may not be populated */ +#define PHYS_SDRAM_1 OMAP34XX_SDRC_CS0 +#define PHYS_SDRAM_1_SIZE (32 << 20) /* at least 32 meg */ +#define PHYS_SDRAM_2 OMAP34XX_SDRC_CS1 + +/* SDRAM Bank Allocation method */ +#define SDRC_R_B_C 1 + +/* + * FLASH and environment organization + */ + +#define PISMO1_ONEN_SIZE GPMC_SIZE_128M /* Configure the PISMO */ + +#define CONFIG_SYS_ONENAND_BASE ONENAND_MAP + +#define ONENAND_ENV_OFFSET 0x260000 /* environment starts here */ + +#define CONFIG_ENV_IS_IN_ONENAND 1 +#define CONFIG_ENV_SIZE (512 << 10) /* Total Size Environment */ +#define CONFIG_ENV_ADDR ONENAND_ENV_OFFSET + +/* + * Size of malloc() pool + */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (128 << 10)) +#define CONFIG_SYS_GBL_DATA_SIZE 128 /* bytes for initial data */ + +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 +#define CONFIG_SYS_INIT_SP_ADDR (LOW_LEVEL_SRAM_STACK - CONFIG_SYS_GBL_DATA_SIZE) + +#endif /* __CONFIG_H */ -- cgit v0.10.2 From 10d6ac94e0aa8bbbde45094e988c87ca971e1f10 Mon Sep 17 00:00:00 2001 From: Ben Gardiner Date: Thu, 14 Oct 2010 17:26:17 -0400 Subject: davinci_nand, trivial : use symbolic ECC start command The ECC calculations were started by writing 1 << 13 to the nand FCR register; that value is also defined as DAVINCI_NANDFCR_4BIT_CALC_START in emif_defs.h. This patch substitutes the macro DAVINCI_NANDFCR_4BIT_CALC_START for the magic number '1 << 13'. Signed-off-by: Ben Gardiner Signed-off-by: Sandeep Paulraj diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index c5a86d6..d41579c 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -481,7 +481,8 @@ static int nand_davinci_4bit_correct_data(struct mtd_info *mtd, uint8_t *dat, * Set the addr_calc_st bit(bit no 13) in the NAND Flash Control * register to 1. */ - __raw_writel(1 << 13, &davinci_emif_regs->nandfcr); + __raw_writel(DAVINCI_NANDFCR_4BIT_CALC_START, + &davinci_emif_regs->nandfcr); /* * Wait for the corr_state field (bits 8 to 11) in the -- cgit v0.10.2 From 756d1fe7ac96822f2125cddde08ccc608bd69a24 Mon Sep 17 00:00:00 2001 From: Ben Gardiner Date: Thu, 14 Oct 2010 17:26:19 -0400 Subject: da850evm : enable NAND even when not in NAND boot mode There is currently no NAND pinmux enabled by the da850evm board setup code. This is fine when booting from NAND since the early boot code (UBL) will setup the pinmux; however, when the boot mode is any other setting NAND is unusable when enabled in the config. This patch adds a pinmux list for NAND and enables it when NAND is enabled in the config. Tested by booting from SPI on the da850evm and verifying NAND was usable. Signed-off-by: Ben Gardiner CC: Nick Thompson Signed-off-by: Sandeep Paulraj diff --git a/board/davinci/da8xxevm/da850evm.c b/board/davinci/da8xxevm/da850evm.c index eeb456c..f84adb9 100644 --- a/board/davinci/da8xxevm/da850evm.c +++ b/board/davinci/da8xxevm/da850evm.c @@ -54,12 +54,34 @@ static const struct pinmux_config i2c_pins[] = { { pinmux(4), 2, 3 } }; +#ifdef CONFIG_NAND_DAVINCI +const struct pinmux_config nand_pins[] = { + { pinmux(7), 1, 1 }, + { pinmux(7), 1, 2 }, + { pinmux(7), 1, 4 }, + { pinmux(7), 1, 5 }, + { pinmux(9), 1, 0 }, + { pinmux(9), 1, 1 }, + { pinmux(9), 1, 2 }, + { pinmux(9), 1, 3 }, + { pinmux(9), 1, 4 }, + { pinmux(9), 1, 5 }, + { pinmux(9), 1, 6 }, + { pinmux(9), 1, 7 }, + { pinmux(12), 1, 5 }, + { pinmux(12), 1, 6 } +}; +#endif + static const struct pinmux_resource pinmuxes[] = { #ifdef CONFIG_SPI_FLASH PINMUX_ITEM(spi1_pins), #endif PINMUX_ITEM(uart_pins), PINMUX_ITEM(i2c_pins), +#ifdef CONFIG_NAND_DAVINCI + PINMUX_ITEM(nand_pins), +#endif }; static const struct lpsc_resource lpsc[] = { -- cgit v0.10.2 From a3f88293ddd13facd734769c1664d35ab4ed681f Mon Sep 17 00:00:00 2001 From: Ben Gardiner Date: Thu, 14 Oct 2010 17:26:22 -0400 Subject: da850evm: setup the NAND flash timings The default NAND flash timings are very conservative. This patch assigns the timings reccomended in the recent linux kernel patch [1] from Sekhar Nori. The speedup, as reported in that patch, is 5.3x for reads. [1] http://www.spinics.net/lists/arm-kernel/msg100278.html Signed-off-by: Ben Gardiner CC: Sekhar Nori Signed-off-by: Sandeep Paulraj diff --git a/board/davinci/da8xxevm/da850evm.c b/board/davinci/da8xxevm/da850evm.c index f84adb9..0eb9e29 100644 --- a/board/davinci/da8xxevm/da850evm.c +++ b/board/davinci/da8xxevm/da850evm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "../common/misc.h" #include "common.h" @@ -98,6 +99,23 @@ int board_init(void) irq_init(); #endif + +#ifdef CONFIG_NAND_DAVINCI + /* + * NAND CS setup - cycle counts based on da850evm NAND timings in the + * Linux kernel @ 25MHz EMIFA + */ + writel((DAVINCI_ABCR_WSETUP(0) | + DAVINCI_ABCR_WSTROBE(0) | + DAVINCI_ABCR_WHOLD(0) | + DAVINCI_ABCR_RSETUP(0) | + DAVINCI_ABCR_RSTROBE(1) | + DAVINCI_ABCR_RHOLD(0) | + DAVINCI_ABCR_TA(0) | + DAVINCI_ABCR_ASIZE_8BIT), + &davinci_emif_regs->ab2cr); /* CS3 */ +#endif + /* arch number of the board */ gd->bd->bi_arch_number = MACH_TYPE_DAVINCI_DA850_EVM; -- cgit v0.10.2 From 6b2c6468952749ec3a9acc5cd9ee4bc4e7a5a59b Mon Sep 17 00:00:00 2001 From: Ben Gardiner Date: Thu, 14 Oct 2010 17:26:25 -0400 Subject: da850evm: setup NAND support under CONFIG_USE_NAND The current da850evm config is missing the pieces for NAND support that can be found in Sandeep's u-boot-davinci tree [1]. This patch adds NAND support in the spirit of the support in the u-boot-davinci tree where NAND support for the da850evm can be enabled by putting a single '#define CONFIG_USE_NAND' at the top of the include/configs/da850evm.h file. [1] http://arago-project.org/git/people/?p=sandeep/u-boot-davinci.git;a=tree Signed-off-by: Ben Gardiner Signed-off-by: Sandeep Paulraj diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h index e0a3bae..0320917 100644 --- a/include/configs/da850evm.h +++ b/include/configs/da850evm.h @@ -79,6 +79,29 @@ #define CONFIG_SYS_I2C_SLAVE 10 /* Bogus, master-only in U-Boot */ /* + * Flash & Environment + */ +#ifdef CONFIG_USE_NAND +#undef CONFIG_ENV_IS_IN_FLASH +#define CONFIG_NAND_DAVINCI +#define CONFIG_SYS_NO_FLASH +#define CONFIG_ENV_IS_IN_NAND /* U-Boot env in NAND Flash */ +#define CONFIG_ENV_OFFSET 0x0 /* Block 0--not used by bootcode */ +#define CONFIG_ENV_SIZE (128 << 10) +#define CONFIG_SYS_NAND_USE_FLASH_BBT +#define CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST +#define CONFIG_SYS_NAND_PAGE_2K +#define CONFIG_SYS_NAND_CS 3 +#define CONFIG_SYS_NAND_BASE DAVINCI_ASYNC_EMIF_DATA_CE3_BASE +#define CONFIG_SYS_CLE_MASK 0x10 +#define CONFIG_SYS_ALE_MASK 0x8 +#undef CONFIG_SYS_NAND_HW_ECC +#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ +#define NAND_MAX_CHIPS 1 +#define DEF_BOOTM "" +#endif + +/* * U-Boot general configuration */ #define CONFIG_BOOTFILE "uImage" /* Boot file name */ @@ -127,6 +150,12 @@ #undef CONFIG_CMD_PING #endif +#ifdef CONFIG_USE_NAND +#undef CONFIG_CMD_FLASH +#undef CONFIG_CMD_IMLS +#define CONFIG_CMD_NAND +#endif + #if !defined(CONFIG_USE_NAND) && \ !defined(CONFIG_USE_NOR) && \ !defined(CONFIG_USE_SPIFLASH) -- cgit v0.10.2 From 771d028afff6d223f2e9cf7ed8328eb2287f4303 Mon Sep 17 00:00:00 2001 From: Ben Gardiner Date: Thu, 14 Oct 2010 17:26:27 -0400 Subject: da850evm: add mtdpart and ubi commands with NAND support This patch enables also the mtdpart, ubi and ubifs commands when NAND support is enabled. Signed-off-by: Ben Gardiner To: Sudhakar Rajashekhara Signed-off-by: Sandeep Paulraj diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h index 0320917..91dc0c6 100644 --- a/include/configs/da850evm.h +++ b/include/configs/da850evm.h @@ -154,6 +154,14 @@ #undef CONFIG_CMD_FLASH #undef CONFIG_CMD_IMLS #define CONFIG_CMD_NAND + +#define CONFIG_CMD_MTDPARTS +#define CONFIG_MTD_DEVICE +#define CONFIG_MTD_PARTITIONS +#define CONFIG_LZO +#define CONFIG_RBTREE +#define CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS #endif #if !defined(CONFIG_USE_NAND) && \ -- cgit v0.10.2 From 3d248d37e1a176326ac8bf6a39144076707530e3 Mon Sep 17 00:00:00 2001 From: Ben Gardiner Date: Thu, 14 Oct 2010 17:26:29 -0400 Subject: da850evm: basic MII EMAC support The current da850evm support in u-boot/master omits any use of the davinci EMAC. This patch adds basic support for the EMAC using the MII PHY found on the baseboard of the EVM. The MAC address is read from the environment variable 'ethadd'. Note that this is different from the da850evm support in the u-boot omapl1 tree where the MAC address is read from SPI flash. Signed-off-by: Ben Gardiner CC: Sandeep Paulraj CC: Sudhakar Rajashekhara CC: Ben Warren CC: Mike Frysinger Signed-off-by: Sandeep Paulraj diff --git a/board/davinci/da8xxevm/da850evm.c b/board/davinci/da8xxevm/da850evm.c index 0eb9e29..c8c5e1b 100644 --- a/board/davinci/da8xxevm/da850evm.c +++ b/board/davinci/da8xxevm/da850evm.c @@ -23,8 +23,11 @@ #include #include +#include +#include #include #include +#include #include #include "../common/misc.h" #include "common.h" @@ -49,6 +52,28 @@ static const struct pinmux_config uart_pins[] = { { pinmux(4), 2, 5 } }; +#ifdef CONFIG_DRIVER_TI_EMAC +static const struct pinmux_config emac_pins[] = { + { pinmux(2), 8, 1 }, + { pinmux(2), 8, 2 }, + { pinmux(2), 8, 3 }, + { pinmux(2), 8, 4 }, + { pinmux(2), 8, 5 }, + { pinmux(2), 8, 6 }, + { pinmux(2), 8, 7 }, + { pinmux(3), 8, 0 }, + { pinmux(3), 8, 1 }, + { pinmux(3), 8, 2 }, + { pinmux(3), 8, 3 }, + { pinmux(3), 8, 4 }, + { pinmux(3), 8, 5 }, + { pinmux(3), 8, 6 }, + { pinmux(3), 8, 7 }, + { pinmux(4), 8, 0 }, + { pinmux(4), 8, 1 } +}; +#endif /* CONFIG_DRIVER_TI_EMAC */ + /* I2C pin muxer settings */ static const struct pinmux_config i2c_pins[] = { { pinmux(4), 2, 2 }, @@ -142,6 +167,14 @@ int board_init(void) if (davinci_configure_pin_mux_items(pinmuxes, ARRAY_SIZE(pinmuxes))) return 1; +#ifdef CONFIG_DRIVER_TI_EMAC + if (davinci_configure_pin_mux(emac_pins, ARRAY_SIZE(emac_pins)) != 0) + return 1; + /* set cfgchip3 to select MII */ + writel(readl(&davinci_syscfg_regs->cfgchip3) & ~(1 << 8), + &davinci_syscfg_regs->cfgchip3); +#endif /* CONFIG_DRIVER_TI_EMAC */ + /* enable the console UART */ writel((DAVINCI_UART_PWREMU_MGMT_FREE | DAVINCI_UART_PWREMU_MGMT_URRST | DAVINCI_UART_PWREMU_MGMT_UTRST), @@ -149,3 +182,19 @@ int board_init(void) return 0; } + +#ifdef CONFIG_DRIVER_TI_EMAC + +/* + * Initializes on-board ethernet controllers. + */ +int board_eth_init(bd_t *bis) +{ + if (!davinci_emac_initialize()) { + printf("Error: Ethernet init failed!\n"); + return -1; + } + + return 0; +} +#endif /* CONFIG_DRIVER_TI_EMAC */ diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h index 91dc0c6..d544c13 100644 --- a/include/configs/da850evm.h +++ b/include/configs/da850evm.h @@ -26,6 +26,7 @@ /* * Board */ +#define CONFIG_DRIVER_TI_EMAC /* * SoC Configuration @@ -102,6 +103,20 @@ #endif /* + * Network & Ethernet Configuration + */ +#ifdef CONFIG_DRIVER_TI_EMAC +#define CONFIG_EMAC_MDIO_PHY_NUM 0 +#define CONFIG_MII +#define CONFIG_BOOTP_DEFAULT +#define CONFIG_BOOTP_DNS +#define CONFIG_BOOTP_DNS2 +#define CONFIG_BOOTP_SEND_HOSTNAME +#define CONFIG_NET_RETRY_COUNT 10 +#define CONFIG_NET_MULTI +#endif + +/* * U-Boot general configuration */ #define CONFIG_BOOTFILE "uImage" /* Boot file name */ -- cgit v0.10.2 From 59e0d611ad0418245e9600b50bf1374a725c95b6 Mon Sep 17 00:00:00 2001 From: Ben Gardiner Date: Thu, 14 Oct 2010 17:26:32 -0400 Subject: da850evm: fix linux bootparam address This patch fixes the LINUX_BOOT_PARAM_ADDR define to be based off of PHYS_SDRAM_1 instead of CONFIG_SYS_MEMTEST_START. On da830 they are the same thing but on da850 the CONFIG_SYS_MEMSTART define is offset from the PHYS_SDRAM_1 start. Without this patch it is not possible to boot linux on da850 -- bootm hangs at "Uncompressing Linux... done, booting the kernel." Signed-off-by: Ben Gardiner Signed-off-by: Sandeep Paulraj diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h index d544c13..7bf6336 100644 --- a/include/configs/da850evm.h +++ b/include/configs/da850evm.h @@ -138,7 +138,7 @@ /* * Linux Information */ -#define LINUX_BOOT_PARAM_ADDR (CONFIG_SYS_MEMTEST_START + 0x100) +#define LINUX_BOOT_PARAM_ADDR (PHYS_SDRAM_1 + 0x100) #define CONFIG_CMDLINE_TAG #define CONFIG_SETUP_MEMORY_TAGS #define CONFIG_BOOTARGS \ -- cgit v0.10.2