xref: /openbmc/u-boot/drivers/fpga/xilinx.c (revision cf0bcd7d)
1 /*
2  * (C) Copyright 2012-2013, Xilinx, Michal Simek
3  *
4  * (C) Copyright 2002
5  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
6  * Keith Outwater, keith_outwater@mvis.com
7  *
8  * SPDX-License-Identifier:	GPL-2.0+
9  */
10 
11 /*
12  *  Xilinx FPGA support
13  */
14 
15 #include <common.h>
16 #include <fpga.h>
17 #include <virtex2.h>
18 #include <spartan2.h>
19 #include <spartan3.h>
20 #include <zynqpl.h>
21 
22 /* Local Static Functions */
23 static int xilinx_validate(xilinx_desc *desc, char *fn);
24 
25 /* ------------------------------------------------------------------------- */
26 
27 int fpga_is_partial_data(int devnum, size_t img_len)
28 {
29 	const fpga_desc * const desc = fpga_get_desc(devnum);
30 	xilinx_desc *desc_xilinx = desc->devdesc;
31 
32 	/* Check datasize against FPGA size */
33 	if (img_len >= desc_xilinx->size)
34 		return 0;
35 
36 	/* datasize is smaller, must be partial data */
37 	return 1;
38 }
39 
40 int fpga_loadbitstream(int devnum, char *fpgadata, size_t size,
41 		       bitstream_type bstype)
42 {
43 	unsigned int length;
44 	unsigned int swapsize;
45 	unsigned char *dataptr;
46 	unsigned int i;
47 	const fpga_desc *desc;
48 	xilinx_desc *xdesc;
49 
50 	dataptr = (unsigned char *)fpgadata;
51 	/* Find out fpga_description */
52 	desc = fpga_validate(devnum, dataptr, 0, (char *)__func__);
53 	/* Assign xilinx device description */
54 	xdesc = desc->devdesc;
55 
56 	/* skip the first bytes of the bitsteam, their meaning is unknown */
57 	length = (*dataptr << 8) + *(dataptr + 1);
58 	dataptr += 2;
59 	dataptr += length;
60 
61 	/* get design name (identifier, length, string) */
62 	length = (*dataptr << 8) + *(dataptr + 1);
63 	dataptr += 2;
64 	if (*dataptr++ != 0x61) {
65 		debug("%s: Design name id not recognized in bitstream\n",
66 		      __func__);
67 		return FPGA_FAIL;
68 	}
69 
70 	length = (*dataptr << 8) + *(dataptr + 1);
71 	dataptr += 2;
72 	printf("  design filename = \"%s\"\n", dataptr);
73 	dataptr += length;
74 
75 	/* get part number (identifier, length, string) */
76 	if (*dataptr++ != 0x62) {
77 		printf("%s: Part number id not recognized in bitstream\n",
78 		       __func__);
79 		return FPGA_FAIL;
80 	}
81 
82 	length = (*dataptr << 8) + *(dataptr + 1);
83 	dataptr += 2;
84 
85 	if (xdesc->name) {
86 		i = (ulong)strstr((char *)dataptr, xdesc->name);
87 		if (!i) {
88 			printf("%s: Wrong bitstream ID for this device\n",
89 			       __func__);
90 			printf("%s: Bitstream ID %s, current device ID %d/%s\n",
91 			       __func__, dataptr, devnum, xdesc->name);
92 			return FPGA_FAIL;
93 		}
94 	} else {
95 		printf("%s: Please fill correct device ID to xilinx_desc\n",
96 		       __func__);
97 	}
98 	printf("  part number = \"%s\"\n", dataptr);
99 	dataptr += length;
100 
101 	/* get date (identifier, length, string) */
102 	if (*dataptr++ != 0x63) {
103 		printf("%s: Date identifier not recognized in bitstream\n",
104 		       __func__);
105 		return FPGA_FAIL;
106 	}
107 
108 	length = (*dataptr << 8) + *(dataptr+1);
109 	dataptr += 2;
110 	printf("  date = \"%s\"\n", dataptr);
111 	dataptr += length;
112 
113 	/* get time (identifier, length, string) */
114 	if (*dataptr++ != 0x64) {
115 		printf("%s: Time identifier not recognized in bitstream\n",
116 		       __func__);
117 		return FPGA_FAIL;
118 	}
119 
120 	length = (*dataptr << 8) + *(dataptr+1);
121 	dataptr += 2;
122 	printf("  time = \"%s\"\n", dataptr);
123 	dataptr += length;
124 
125 	/* get fpga data length (identifier, length) */
126 	if (*dataptr++ != 0x65) {
127 		printf("%s: Data length id not recognized in bitstream\n",
128 		       __func__);
129 		return FPGA_FAIL;
130 	}
131 	swapsize = ((unsigned int) *dataptr << 24) +
132 		   ((unsigned int) *(dataptr + 1) << 16) +
133 		   ((unsigned int) *(dataptr + 2) << 8) +
134 		   ((unsigned int) *(dataptr + 3));
135 	dataptr += 4;
136 	printf("  bytes in bitstream = %d\n", swapsize);
137 
138 	return fpga_load(devnum, dataptr, swapsize, bstype);
139 }
140 
141 int xilinx_load(xilinx_desc *desc, const void *buf, size_t bsize,
142 		bitstream_type bstype)
143 {
144 	if (!xilinx_validate (desc, (char *)__FUNCTION__)) {
145 		printf ("%s: Invalid device descriptor\n", __FUNCTION__);
146 		return FPGA_FAIL;
147 	}
148 
149 	if (!desc->operations || !desc->operations->load) {
150 		printf("%s: Missing load operation\n", __func__);
151 		return FPGA_FAIL;
152 	}
153 
154 	return desc->operations->load(desc, buf, bsize, bstype);
155 }
156 
157 #if defined(CONFIG_CMD_FPGA_LOADFS)
158 int xilinx_loadfs(xilinx_desc *desc, const void *buf, size_t bsize,
159 		   fpga_fs_info *fpga_fsinfo)
160 {
161 	if (!xilinx_validate(desc, (char *)__func__)) {
162 		printf("%s: Invalid device descriptor\n", __func__);
163 		return FPGA_FAIL;
164 	}
165 
166 	if (!desc->operations || !desc->operations->loadfs) {
167 		printf("%s: Missing loadfs operation\n", __func__);
168 		return FPGA_FAIL;
169 	}
170 
171 	return desc->operations->loadfs(desc, buf, bsize, fpga_fsinfo);
172 }
173 #endif
174 
175 int xilinx_dump(xilinx_desc *desc, const void *buf, size_t bsize)
176 {
177 	if (!xilinx_validate (desc, (char *)__FUNCTION__)) {
178 		printf ("%s: Invalid device descriptor\n", __FUNCTION__);
179 		return FPGA_FAIL;
180 	}
181 
182 	if (!desc->operations || !desc->operations->dump) {
183 		printf("%s: Missing dump operation\n", __func__);
184 		return FPGA_FAIL;
185 	}
186 
187 	return desc->operations->dump(desc, buf, bsize);
188 }
189 
190 int xilinx_info(xilinx_desc *desc)
191 {
192 	int ret_val = FPGA_FAIL;
193 
194 	if (xilinx_validate (desc, (char *)__FUNCTION__)) {
195 		printf ("Family:        \t");
196 		switch (desc->family) {
197 		case xilinx_spartan2:
198 			printf ("Spartan-II\n");
199 			break;
200 		case xilinx_spartan3:
201 			printf ("Spartan-III\n");
202 			break;
203 		case xilinx_virtex2:
204 			printf ("Virtex-II\n");
205 			break;
206 		case xilinx_zynq:
207 			printf("Zynq PL\n");
208 			break;
209 		case xilinx_zynqmp:
210 			printf("ZynqMP PL\n");
211 			break;
212 			/* Add new family types here */
213 		default:
214 			printf ("Unknown family type, %d\n", desc->family);
215 		}
216 
217 		printf ("Interface type:\t");
218 		switch (desc->iface) {
219 		case slave_serial:
220 			printf ("Slave Serial\n");
221 			break;
222 		case master_serial:	/* Not used */
223 			printf ("Master Serial\n");
224 			break;
225 		case slave_parallel:
226 			printf ("Slave Parallel\n");
227 			break;
228 		case jtag_mode:		/* Not used */
229 			printf ("JTAG Mode\n");
230 			break;
231 		case slave_selectmap:
232 			printf ("Slave SelectMap Mode\n");
233 			break;
234 		case master_selectmap:
235 			printf ("Master SelectMap Mode\n");
236 			break;
237 		case devcfg:
238 			printf("Device configuration interface (Zynq)\n");
239 			break;
240 		case csu_dma:
241 			printf("csu_dma configuration interface (ZynqMP)\n");
242 			break;
243 			/* Add new interface types here */
244 		default:
245 			printf ("Unsupported interface type, %d\n", desc->iface);
246 		}
247 
248 		printf("Device Size:   \t%zd bytes\n"
249 		       "Cookie:        \t0x%x (%d)\n",
250 		       desc->size, desc->cookie, desc->cookie);
251 		if (desc->name)
252 			printf("Device name:   \t%s\n", desc->name);
253 
254 		if (desc->iface_fns)
255 			printf ("Device Function Table @ 0x%p\n", desc->iface_fns);
256 		else
257 			printf ("No Device Function Table.\n");
258 
259 		if (desc->operations && desc->operations->info)
260 			desc->operations->info(desc);
261 
262 		ret_val = FPGA_SUCCESS;
263 	} else {
264 		printf ("%s: Invalid device descriptor\n", __FUNCTION__);
265 	}
266 
267 	return ret_val;
268 }
269 
270 /* ------------------------------------------------------------------------- */
271 
272 static int xilinx_validate(xilinx_desc *desc, char *fn)
273 {
274 	int ret_val = false;
275 
276 	if (desc) {
277 		if ((desc->family > min_xilinx_type) &&
278 			(desc->family < max_xilinx_type)) {
279 			if ((desc->iface > min_xilinx_iface_type) &&
280 				(desc->iface < max_xilinx_iface_type)) {
281 				if (desc->size) {
282 					ret_val = true;
283 				} else
284 					printf ("%s: NULL part size\n", fn);
285 			} else
286 				printf ("%s: Invalid Interface type, %d\n",
287 						fn, desc->iface);
288 		} else
289 			printf ("%s: Invalid family type, %d\n", fn, desc->family);
290 	} else
291 		printf ("%s: NULL descriptor!\n", fn);
292 
293 	return ret_val;
294 }
295