1 /*************************************************************** 2 * Project: 3 * CPLD SlaveSerial Configuration via embedded microprocessor. 4 * 5 * Copyright info: 6 * 7 * This is free software; you can redistribute it and/or modify 8 * it as you like. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 * 14 * Description: 15 * 16 * This is the main source file that will allow a microprocessor 17 * to configure Xilinx Virtex, Virtex-E, Virtex-EM, Virtex-II, 18 * and Spartan-II devices via the SlaveSerial Configuration Mode. 19 * This code is discussed in Xilinx Application Note, XAPP502. 20 * 21 * History: 22 * 3-October-2001 MN/MP - Created 23 * 20-August-2008 Renesas Solutions - Modified to SH7723 24 ****************************************************************/ 25 26 #include <common.h> 27 28 /* Serial */ 29 #define SCIF_BASE 0xffe00000 /* SCIF0 */ 30 #define SCSMR (vu_short *)(SCIF_BASE + 0x00) 31 #define SCBRR (vu_char *)(SCIF_BASE + 0x04) 32 #define SCSCR (vu_short *)(SCIF_BASE + 0x08) 33 #define SC_TDR (vu_char *)(SCIF_BASE + 0x0C) 34 #define SC_SR (vu_short *)(SCIF_BASE + 0x10) 35 #define SCFCR (vu_short *)(SCIF_BASE + 0x18) 36 #define RFCR (vu_long *)0xFE400020 37 38 #define SCSCR_INIT 0x0038 39 #define SCSCR_CLR 0x0000 40 #define SCFCR_INIT 0x0006 41 #define SCSMR_INIT 0x0080 42 #define RFCR_CLR 0xA400 43 #define SCI_TD_E 0x0020 44 #define SCI_TDRE_CLEAR 0x00df 45 46 #define BPS_SETTING_VALUE 1 /* 12.5MHz */ 47 #define WAIT_RFCR_COUNTER 500 48 49 /* CPLD data size */ 50 #define CPLD_DATA_SIZE 169216 51 52 /* out */ 53 #define CPLD_PFC_ADR ((vu_short *)0xA4050112) 54 55 #define CPLD_PROG_ADR ((vu_char *)0xA4050132) 56 #define CPLD_PROG_DAT 0x80 57 58 /* in */ 59 #define CPLD_INIT_ADR ((vu_char *)0xA4050132) 60 #define CPLD_INIT_DAT 0x40 61 #define CPLD_DONE_ADR ((vu_char *)0xA4050132) 62 #define CPLD_DONE_DAT 0x20 63 64 #define HIZCRB ((vu_short *)0xA405015A) 65 66 /* data */ 67 #define CPLD_NOMAL_START 0xA0A80000 68 #define CPLD_SAFE_START 0xA0AC0000 69 #define MODE_SW (vu_char *)0xA405012A 70 71 static void init_cpld_loader(void) 72 { 73 74 *SCSCR = SCSCR_CLR; 75 *SCFCR = SCFCR_INIT; 76 *SCSMR = SCSMR_INIT; 77 78 *SCBRR = BPS_SETTING_VALUE; 79 80 *RFCR = RFCR_CLR; /* Refresh counter clear */ 81 82 while (*RFCR < WAIT_RFCR_COUNTER) 83 ; 84 85 *SCFCR = 0x0; /* RTRG=00, TTRG=00 */ 86 /* MCE=0,TFRST=0,RFRST=0,LOOP=0 */ 87 *SCSCR = SCSCR_INIT; 88 } 89 90 static int check_write_ready(void) 91 { 92 u16 status = *SC_SR; 93 return status & SCI_TD_E; 94 } 95 96 static void write_cpld_data(char ch) 97 { 98 while (!check_write_ready()) 99 ; 100 101 *SC_TDR = ch; 102 *SC_SR; 103 *SC_SR = SCI_TDRE_CLEAR; 104 } 105 106 static int delay(void) 107 { 108 int i; 109 int c = 0; 110 for (i = 0; i < 200; i++) { 111 c = *(volatile int *)0xa0000000; 112 } 113 return c; 114 } 115 116 /*********************************************************************** 117 * 118 * Function: slave_serial 119 * 120 * Description: Initiates SlaveSerial Configuration. 121 * Calls ShiftDataOut() to output serial data 122 * 123 ***********************************************************************/ 124 static void slave_serial(void) 125 { 126 int i; 127 unsigned char *flash; 128 129 *CPLD_PROG_ADR |= CPLD_PROG_DAT; /* PROGRAM_OE HIGH */ 130 delay(); 131 132 /* 133 * Toggle Program Pin by Toggling Program_OE bit 134 * This is accomplished by writing to the Program Register in the CPLD 135 * 136 * NOTE: The Program_OE bit should be driven high to bring the Virtex 137 * Program Pin low. Likewise, it should be driven low 138 * to bring the Virtex Program Pin to High-Z 139 */ 140 141 *CPLD_PROG_ADR &= ~CPLD_PROG_DAT; /* PROGRAM_OE LOW */ 142 delay(); 143 144 /* 145 * Bring Program High-Z 146 * (Drive Program_OE bit low to bring Virtex Program Pin to High-Z 147 */ 148 149 /* Program_OE bit Low brings the Virtex Program Pin to High Z: */ 150 *CPLD_PROG_ADR |= CPLD_PROG_DAT; /* PROGRAM_OE HIGH */ 151 152 while ((*CPLD_INIT_ADR & CPLD_INIT_DAT) == 0) 153 delay(); 154 155 /* Begin Slave-Serial Configuration */ 156 flash = (unsigned char *)CPLD_NOMAL_START; 157 158 for (i = 0; i < CPLD_DATA_SIZE; i++) 159 write_cpld_data(*flash++); 160 } 161 162 /*********************************************************************** 163 * 164 * Function: check_done_bit 165 * 166 * Description: This function takes monitors the CPLD Input Register 167 * by checking the status of the DONE bit in that Register. 168 * By doing so, it monitors the Xilinx Virtex device's DONE 169 * Pin to see if configuration bitstream has been properly 170 * loaded 171 * 172 ***********************************************************************/ 173 static void check_done_bit(void) 174 { 175 while (!(*CPLD_DONE_ADR & CPLD_DONE_DAT)) 176 ; 177 } 178 179 /*********************************************************************** 180 * 181 * Function: init_cpld 182 * 183 * Description: Begins Slave Serial configuration of Xilinx FPGA 184 * 185 ***********************************************************************/ 186 void init_cpld(void) 187 { 188 /* Init serial device */ 189 init_cpld_loader(); 190 191 if (*CPLD_DONE_ADR & CPLD_DONE_DAT) /* Already DONE */ 192 return; 193 194 *HIZCRB = 0x0000; 195 *CPLD_PFC_ADR = 0x7c00; /* FPGA PROG = OUTPUT */ 196 197 /* write CPLD data from NOR flash to device */ 198 slave_serial(); 199 200 /* 201 * Monitor the DONE bit in the CPLD Input Register to see if 202 * configuration successful 203 */ 204 205 check_done_bit(); 206 } 207