blob: 5d9dc9387ed74f68cb1406ddfd4e0883c5235819 [file] [log] [blame]
Nobuhiro Iwamatsu3e590432008-08-22 17:39:09 +09001/***************************************************************
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
Nobuhiro Iwamatsu3e590432008-08-22 17:39:09 +090064/* data */
65#define CPLD_NOMAL_START 0xA0A80000
66#define CPLD_SAFE_START 0xA0AC0000
67#define MODE_SW (vu_char *)0xA405012A
68
69static void init_cpld_loader(void)
70{
71
72 *SCSCR = SCSCR_CLR;
73 *SCFCR = SCFCR_INIT;
74 *SCSMR = SCSMR_INIT;
75
76 *SCBRR = BPS_SETTING_VALUE;
77
78 *RFCR = RFCR_CLR; /* Refresh counter clear */
79
80 while (*RFCR < WAIT_RFCR_COUNTER)
81 ;
82
83 *SCFCR = 0x0; /* RTRG=00, TTRG=00 */
84 /* MCE=0,TFRST=0,RFRST=0,LOOP=0 */
85 *SCSCR = SCSCR_INIT;
86}
87
88static int check_write_ready(void)
89{
90 u16 status = *SC_SR;
91 return status & SCI_TD_E;
92}
93
94static void write_cpld_data(char ch)
95{
96 while (!check_write_ready())
97 ;
98
99 *SC_TDR = ch;
100 *SC_SR;
101 *SC_SR = SCI_TDRE_CLEAR;
102}
103
104static int delay(void)
105{
106 int i;
107 int c = 0;
108 for (i = 0; i < 200; i++) {
109 c = *(volatile int *)0xa0000000;
110 }
111 return c;
112}
113
114/***********************************************************************
115 *
116 * Function: slave_serial
117 *
118 * Description: Initiates SlaveSerial Configuration.
119 * Calls ShiftDataOut() to output serial data
120 *
121 ***********************************************************************/
122static void slave_serial(void)
123{
124 int i;
125 unsigned char *flash;
126
127 *CPLD_PROG_ADR |= CPLD_PROG_DAT; /* PROGRAM_OE HIGH */
128 delay();
129
130 /*
131 * Toggle Program Pin by Toggling Program_OE bit
132 * This is accomplished by writing to the Program Register in the CPLD
133 *
134 * NOTE: The Program_OE bit should be driven high to bring the Virtex
135 * Program Pin low. Likewise, it should be driven low
136 * to bring the Virtex Program Pin to High-Z
137 */
138
139 *CPLD_PROG_ADR &= ~CPLD_PROG_DAT; /* PROGRAM_OE LOW */
140 delay();
141
142 /*
143 * Bring Program High-Z
144 * (Drive Program_OE bit low to bring Virtex Program Pin to High-Z
145 */
146
147 /* Program_OE bit Low brings the Virtex Program Pin to High Z: */
148 *CPLD_PROG_ADR |= CPLD_PROG_DAT; /* PROGRAM_OE HIGH */
149
150 while ((*CPLD_INIT_ADR & CPLD_INIT_DAT) == 0)
151 delay();
152
153 /* Begin Slave-Serial Configuration */
154 flash = (unsigned char *)CPLD_NOMAL_START;
155
156 for (i = 0; i < CPLD_DATA_SIZE; i++)
157 write_cpld_data(*flash++);
158}
159
160/***********************************************************************
161 *
162 * Function: check_done_bit
163 *
164 * Description: This function takes monitors the CPLD Input Register
165 * by checking the status of the DONE bit in that Register.
166 * By doing so, it monitors the Xilinx Virtex device's DONE
167 * Pin to see if configuration bitstream has been properly
168 * loaded
169 *
170 ***********************************************************************/
171static void check_done_bit(void)
172{
173 while (!(*CPLD_DONE_ADR & CPLD_DONE_DAT))
174 ;
175}
176
177/***********************************************************************
178 *
179 * Function: init_cpld
180 *
181 * Description: Begins Slave Serial configuration of Xilinx FPGA
182 *
183 ***********************************************************************/
184void init_cpld(void)
185{
186 /* Init serial device */
187 init_cpld_loader();
188
189 if (*CPLD_DONE_ADR & CPLD_DONE_DAT) /* Already DONE */
190 return;
191
Marek Vasutbe69fa72018-08-29 03:18:30 +0200192 *((vu_short *)HIZCRB) = 0x0000;
Nobuhiro Iwamatsu3e590432008-08-22 17:39:09 +0900193 *CPLD_PFC_ADR = 0x7c00; /* FPGA PROG = OUTPUT */
194
195 /* write CPLD data from NOR flash to device */
196 slave_serial();
197
198 /*
199 * Monitor the DONE bit in the CPLD Input Register to see if
200 * configuration successful
201 */
202
203 check_done_bit();
204}