1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2006
4  * Heiko Schocher, hs@denx.de
5  * Based on ACE1XK.c
6  */
7 
8 #include <common.h>		/* core U-Boot definitions */
9 #include <altera.h>
10 #include <ACEX1K.h>		/* ACEX device family */
11 #include <linux/delay.h>
12 
13 /* Define FPGA_DEBUG to get debug printf's */
14 #ifdef	FPGA_DEBUG
15 #define PRINTF(fmt, args...)	printf(fmt, ##args)
16 #else
17 #define PRINTF(fmt, args...)
18 #endif
19 
20 /* Note: The assumption is that we cannot possibly run fast enough to
21  * overrun the device (the Slave Parallel mode can free run at 50MHz).
22  * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
23  * the board config file to slow things down.
24  */
25 #ifndef CONFIG_FPGA_DELAY
26 #define CONFIG_FPGA_DELAY()
27 #endif
28 
29 #ifndef CONFIG_SYS_FPGA_WAIT
30 #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ / 10		/* 100 ms */
31 #endif
32 
33 static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize);
34 static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize);
35 /* static int CYC2_ps_info( Altera_desc *desc ); */
36 
37 /* ------------------------------------------------------------------------- */
38 /* CYCLON2 Generic Implementation */
CYC2_load(Altera_desc * desc,const void * buf,size_t bsize)39 int CYC2_load(Altera_desc *desc, const void *buf, size_t bsize)
40 {
41 	int ret_val = FPGA_FAIL;
42 
43 	switch (desc->iface) {
44 	case passive_serial:
45 		PRINTF("%s: Launching Passive Serial Loader\n", __func__);
46 		ret_val = CYC2_ps_load(desc, buf, bsize);
47 		break;
48 
49 	case fast_passive_parallel:
50 		/* Fast Passive Parallel (FPP) and PS only differ in what is
51 		 * done in the write() callback. Use the existing PS load
52 		 * function for FPP, too.
53 		 */
54 		PRINTF("%s: Launching Fast Passive Parallel Loader\n",
55 		       __func__);
56 		ret_val = CYC2_ps_load(desc, buf, bsize);
57 		break;
58 
59 		/* Add new interface types here */
60 
61 	default:
62 		printf("%s: Unsupported interface type, %d\n",
63 		       __func__, desc->iface);
64 	}
65 
66 	return ret_val;
67 }
68 
CYC2_dump(Altera_desc * desc,const void * buf,size_t bsize)69 int CYC2_dump(Altera_desc *desc, const void *buf, size_t bsize)
70 {
71 	int ret_val = FPGA_FAIL;
72 
73 	switch (desc->iface) {
74 	case passive_serial:
75 		PRINTF("%s: Launching Passive Serial Dump\n", __func__);
76 		ret_val = CYC2_ps_dump(desc, buf, bsize);
77 		break;
78 
79 		/* Add new interface types here */
80 
81 	default:
82 		printf("%s: Unsupported interface type, %d\n",
83 		       __func__, desc->iface);
84 	}
85 
86 	return ret_val;
87 }
88 
CYC2_info(Altera_desc * desc)89 int CYC2_info(Altera_desc *desc)
90 {
91 	return FPGA_SUCCESS;
92 }
93 
94 /* ------------------------------------------------------------------------- */
95 /* CYCLON2 Passive Serial Generic Implementation                             */
CYC2_ps_load(Altera_desc * desc,const void * buf,size_t bsize)96 static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize)
97 {
98 	int ret_val = FPGA_FAIL;	/* assume the worst */
99 	Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns;
100 	int	ret = 0;
101 
102 	PRINTF("%s: start with interface functions @ 0x%p\n",
103 	       __func__, fn);
104 
105 	if (fn) {
106 		int cookie = desc->cookie;	/* make a local copy */
107 		unsigned long ts;		/* timestamp */
108 
109 		PRINTF("%s: Function Table:\n"
110 				"ptr:\t0x%p\n"
111 				"struct: 0x%p\n"
112 				"config:\t0x%p\n"
113 				"status:\t0x%p\n"
114 				"write:\t0x%p\n"
115 				"done:\t0x%p\n\n",
116 				__func__, &fn, fn, fn->config, fn->status,
117 				fn->write, fn->done);
118 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
119 		printf("Loading FPGA Device %d...", cookie);
120 #endif
121 
122 		/*
123 		 * Run the pre configuration function if there is one.
124 		 */
125 		if (*fn->pre)
126 			(*fn->pre) (cookie);
127 
128 		/* Establish the initial state */
129 		(*fn->config) (false, true, cookie);	/* De-assert nCONFIG */
130 		udelay(100);
131 		(*fn->config) (true, true, cookie);	/* Assert nCONFIG */
132 
133 		udelay(2);		/* T_cfg > 2us	*/
134 
135 		/* Wait for nSTATUS to be asserted */
136 		ts = get_timer(0);		/* get current time */
137 		do {
138 			CONFIG_FPGA_DELAY();
139 			if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
140 				/* check the time */
141 				puts("** Timeout waiting for STATUS to go high.\n");
142 				(*fn->abort) (cookie);
143 				return FPGA_FAIL;
144 			}
145 		} while (!(*fn->status) (cookie));
146 
147 		/* Get ready for the burn */
148 		CONFIG_FPGA_DELAY();
149 
150 		ret = (*fn->write) (buf, bsize, true, cookie);
151 		if (ret) {
152 			puts("** Write failed.\n");
153 			(*fn->abort) (cookie);
154 			return FPGA_FAIL;
155 		}
156 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
157 		puts(" OK? ...");
158 #endif
159 
160 		CONFIG_FPGA_DELAY();
161 
162 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
163 		putc(' ');			/* terminate the dotted line */
164 #endif
165 
166 		/*
167 		 * Checking FPGA's CONF_DONE signal - correctly booted ?
168 		 */
169 
170 		if (!(*fn->done) (cookie)) {
171 			puts("** Booting failed! CONF_DONE is still deasserted.\n");
172 			(*fn->abort) (cookie);
173 			return FPGA_FAIL;
174 		}
175 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
176 		puts(" OK\n");
177 #endif
178 
179 		ret_val = FPGA_SUCCESS;
180 
181 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
182 		if (ret_val == FPGA_SUCCESS)
183 			puts("Done.\n");
184 		else
185 			puts("Fail.\n");
186 #endif
187 
188 		/*
189 		 * Run the post configuration function if there is one.
190 		 */
191 		if (*fn->post)
192 			(*fn->post) (cookie);
193 	} else {
194 		printf("%s: NULL Interface function table!\n", __func__);
195 	}
196 
197 	return ret_val;
198 }
199 
CYC2_ps_dump(Altera_desc * desc,const void * buf,size_t bsize)200 static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize)
201 {
202 	/* Readback is only available through the Slave Parallel and         */
203 	/* boundary-scan interfaces.                                         */
204 	printf("%s: Passive Serial Dumping is unavailable\n", __func__);
205 	return FPGA_FAIL;
206 }
207