/*************************************************************** * Project: * CPLD SlaveSerial Configuration via embedded microprocessor. * * Copyright info: * * This is free software; you can redistribute it and/or modify * it as you like. * * 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. * * Description: * * This is the main source file that will allow a microprocessor * to configure Xilinx Virtex, Virtex-E, Virtex-EM, Virtex-II, * and Spartan-II devices via the SlaveSerial Configuration Mode. * This code is discussed in Xilinx Application Note, XAPP502. * * History: * 3-October-2001 MN/MP - Created * 20-August-2008 Renesas Solutions - Modified to SH7723 ****************************************************************/ #include <common.h> /* Serial */ #define SCIF_BASE 0xffe00000 /* SCIF0 */ #define SCSMR (vu_short *)(SCIF_BASE + 0x00) #define SCBRR (vu_char *)(SCIF_BASE + 0x04) #define SCSCR (vu_short *)(SCIF_BASE + 0x08) #define SC_TDR (vu_char *)(SCIF_BASE + 0x0C) #define SC_SR (vu_short *)(SCIF_BASE + 0x10) #define SCFCR (vu_short *)(SCIF_BASE + 0x18) #define RFCR (vu_long *)0xFE400020 #define SCSCR_INIT 0x0038 #define SCSCR_CLR 0x0000 #define SCFCR_INIT 0x0006 #define SCSMR_INIT 0x0080 #define RFCR_CLR 0xA400 #define SCI_TD_E 0x0020 #define SCI_TDRE_CLEAR 0x00df #define BPS_SETTING_VALUE 1 /* 12.5MHz */ #define WAIT_RFCR_COUNTER 500 /* CPLD data size */ #define CPLD_DATA_SIZE 169216 /* out */ #define CPLD_PFC_ADR ((vu_short *)0xA4050112) #define CPLD_PROG_ADR ((vu_char *)0xA4050132) #define CPLD_PROG_DAT 0x80 /* in */ #define CPLD_INIT_ADR ((vu_char *)0xA4050132) #define CPLD_INIT_DAT 0x40 #define CPLD_DONE_ADR ((vu_char *)0xA4050132) #define CPLD_DONE_DAT 0x20 #define HIZCRB ((vu_short *)0xA405015A) /* data */ #define CPLD_NOMAL_START 0xA0A80000 #define CPLD_SAFE_START 0xA0AC0000 #define MODE_SW (vu_char *)0xA405012A static void init_cpld_loader(void) { *SCSCR = SCSCR_CLR; *SCFCR = SCFCR_INIT; *SCSMR = SCSMR_INIT; *SCBRR = BPS_SETTING_VALUE; *RFCR = RFCR_CLR; /* Refresh counter clear */ while (*RFCR < WAIT_RFCR_COUNTER) ; *SCFCR = 0x0; /* RTRG=00, TTRG=00 */ /* MCE=0,TFRST=0,RFRST=0,LOOP=0 */ *SCSCR = SCSCR_INIT; } static int check_write_ready(void) { u16 status = *SC_SR; return status & SCI_TD_E; } static void write_cpld_data(char ch) { while (!check_write_ready()) ; *SC_TDR = ch; *SC_SR; *SC_SR = SCI_TDRE_CLEAR; } static int delay(void) { int i; int c = 0; for (i = 0; i < 200; i++) { c = *(volatile int *)0xa0000000; } return c; } /*********************************************************************** * * Function: slave_serial * * Description: Initiates SlaveSerial Configuration. * Calls ShiftDataOut() to output serial data * ***********************************************************************/ static void slave_serial(void) { int i; unsigned char *flash; *CPLD_PROG_ADR |= CPLD_PROG_DAT; /* PROGRAM_OE HIGH */ delay(); /* * Toggle Program Pin by Toggling Program_OE bit * This is accomplished by writing to the Program Register in the CPLD * * NOTE: The Program_OE bit should be driven high to bring the Virtex * Program Pin low. Likewise, it should be driven low * to bring the Virtex Program Pin to High-Z */ *CPLD_PROG_ADR &= ~CPLD_PROG_DAT; /* PROGRAM_OE LOW */ delay(); /* * Bring Program High-Z * (Drive Program_OE bit low to bring Virtex Program Pin to High-Z */ /* Program_OE bit Low brings the Virtex Program Pin to High Z: */ *CPLD_PROG_ADR |= CPLD_PROG_DAT; /* PROGRAM_OE HIGH */ while ((*CPLD_INIT_ADR & CPLD_INIT_DAT) == 0) delay(); /* Begin Slave-Serial Configuration */ flash = (unsigned char *)CPLD_NOMAL_START; for (i = 0; i < CPLD_DATA_SIZE; i++) write_cpld_data(*flash++); } /*********************************************************************** * * Function: check_done_bit * * Description: This function takes monitors the CPLD Input Register * by checking the status of the DONE bit in that Register. * By doing so, it monitors the Xilinx Virtex device's DONE * Pin to see if configuration bitstream has been properly * loaded * ***********************************************************************/ static void check_done_bit(void) { while (!(*CPLD_DONE_ADR & CPLD_DONE_DAT)) ; } /*********************************************************************** * * Function: init_cpld * * Description: Begins Slave Serial configuration of Xilinx FPGA * ***********************************************************************/ void init_cpld(void) { /* Init serial device */ init_cpld_loader(); if (*CPLD_DONE_ADR & CPLD_DONE_DAT) /* Already DONE */ return; *HIZCRB = 0x0000; *CPLD_PFC_ADR = 0x7c00; /* FPGA PROG = OUTPUT */ /* write CPLD data from NOR flash to device */ slave_serial(); /* * Monitor the DONE bit in the CPLD Input Register to see if * configuration successful */ check_done_bit(); }