1 /*
2  * Copyright (c) 2021-2022 Antmicro <www.antmicro.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT xlnx_fpga
8 
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/fpga.h>
11 #include "fpga_zynqmp.h"
12 #include <errno.h>
13 #include <string.h>
14 #include <zephyr/sys/byteorder.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 
18 #include <zephyr/logging/log.h>
19 LOG_MODULE_REGISTER(fpga_zynqmp);
20 
power_up_fpga(void)21 static void power_up_fpga(void)
22 {
23 	PMU_GLOBAL_PWRUP_EN = PWR_PL_MASK;
24 	PMU_REQ_PWRUP_TRIG = PWR_PL_MASK;
25 
26 	while (PWR_STATUS & PWR_PL_MASK) {
27 	};
28 }
29 
30 struct zynqmp_fpga_data {
31 	char FPGA_info[16];
32 };
33 
update_part_name(const struct device * dev)34 static void update_part_name(const struct device *dev)
35 {
36 	struct zynqmp_fpga_data *data = dev->data;
37 
38 	int zu_number = 0;
39 
40 	switch (IDCODE & IDCODE_MASK) {
41 	case ZU2_IDCODE:
42 		zu_number = 2;
43 		break;
44 	case ZU3_IDCODE:
45 		zu_number = 3;
46 		break;
47 	case ZU4_IDCODE:
48 		zu_number = 4;
49 		break;
50 	case ZU5_IDCODE:
51 		zu_number = 5;
52 		break;
53 	case ZU6_IDCODE:
54 		zu_number = 6;
55 		break;
56 	case ZU7_IDCODE:
57 		zu_number = 7;
58 		break;
59 	case ZU9_IDCODE:
60 		zu_number = 9;
61 		break;
62 	case ZU11_IDCODE:
63 		zu_number = 11;
64 		break;
65 	case ZU15_IDCODE:
66 		zu_number = 15;
67 		break;
68 	case ZU17_IDCODE:
69 		zu_number = 17;
70 		break;
71 	case ZU19_IDCODE:
72 		zu_number = 19;
73 		break;
74 	case ZU21_IDCODE:
75 		zu_number = 21;
76 		break;
77 	case ZU25_IDCODE:
78 		zu_number = 25;
79 		break;
80 	case ZU27_IDCODE:
81 		zu_number = 27;
82 		break;
83 	case ZU28_IDCODE:
84 		zu_number = 28;
85 		break;
86 	case ZU29_IDCODE:
87 		zu_number = 29;
88 		break;
89 	case ZU39_IDCODE:
90 		zu_number = 39;
91 		break;
92 	case ZU43_IDCODE:
93 		zu_number = 43;
94 		break;
95 	case ZU46_IDCODE:
96 		zu_number = 46;
97 		break;
98 	case ZU47_IDCODE:
99 		zu_number = 47;
100 		break;
101 	case ZU48_IDCODE:
102 		zu_number = 48;
103 		break;
104 	case ZU49_IDCODE:
105 		zu_number = 49;
106 		break;
107 	}
108 
109 	if (zu_number == 0) {
110 		snprintf(data->FPGA_info, sizeof(data->FPGA_info), "unknown");
111 	} else {
112 		snprintf(data->FPGA_info, sizeof(data->FPGA_info), "Part name: ZU%d", zu_number);
113 	}
114 
115 }
116 
117 /*
118  * This function is responsible for shifting the bitstream
119  * by its header and extracting information from this header.
120  * The bitstream header has 5 sections starting with the letters a,b,c...
121  * Each section has the following structure:
122  * [key][length of data][data]
123  */
parse_header(const struct device * dev,uint32_t * image_ptr,uint32_t * img_size)124 static uint32_t *parse_header(const struct device *dev, uint32_t *image_ptr,
125 		       uint32_t *img_size)
126 {
127 	unsigned char *header = (unsigned char *)image_ptr;
128 
129 	uint32_t length = XLNX_BITSTREAM_SECTION_LENGTH(header);
130 
131 	/* shift to the next section*/
132 	header += 0x4U + length;
133 
134 	if (*header++ != 'a') {
135 		LOG_ERR("Incorrect bitstream format");
136 		return NULL;
137 	}
138 
139 	length = XLNX_BITSTREAM_SECTION_LENGTH(header);
140 	/* shift to the data section*/
141 	header += 0x2U;
142 
143 	LOG_DBG("Design name = %s", header);
144 
145 	header += length;
146 
147 	if (*header++ != 'b') {
148 		LOG_ERR("Incorrect bitstream format");
149 		return NULL;
150 	}
151 
152 	length = XLNX_BITSTREAM_SECTION_LENGTH(header);
153 	/* shift to the data section*/
154 	header += 0x2U;
155 	LOG_DBG("Part name = %s", header);
156 
157 	header += length;
158 
159 	if (*header++ != 'c') {
160 		LOG_ERR("Incorrect bitstream format");
161 		return NULL;
162 	}
163 
164 	length = XLNX_BITSTREAM_SECTION_LENGTH(header);
165 	/* shift to the data section*/
166 	header += 0x2U;
167 
168 	LOG_DBG("Date =  %s", header);
169 
170 	header += length;
171 
172 	if (*header++ != 'd') {
173 		LOG_ERR("Incorrect bitstream format");
174 		return NULL;
175 	}
176 
177 	length = XLNX_BITSTREAM_SECTION_LENGTH(header);
178 	/* shift to the data section*/
179 	header += 0x2U;
180 
181 	LOG_DBG("Time =  %s", header);
182 
183 	header += length;
184 
185 	if (*header++ != 'e') {
186 		LOG_ERR("Incorrect bitstream format");
187 		return NULL;
188 	}
189 
190 	/*
191 	 * The last section is the raw bitstream.
192 	 * It is preceded by its size, which is needed for DMA transfer.
193 	 */
194 	*img_size =
195 		((uint32_t)*header << 24) | ((uint32_t) *(header + 1) << 16) |
196 		((uint32_t) *(header + 2) << 8) | ((uint32_t) *(header + 3));
197 
198 	return (uint32_t *)header;
199 }
200 
csudma_transfer(uint32_t size)201 static int csudma_transfer(uint32_t size)
202 {
203 	/* setup the source DMA channel */
204 	CSUDMA_SRC_ADDR = (uint32_t)BITSTREAM & CSUDMA_SRC_ADDR_MASK;
205 	CSUDMA_SRC_ADDR_MSB = 0;
206 	CSUDMA_SRC_SIZE = size << CSUDMA_SRC_SIZE_SHIFT;
207 
208 	/* wait for the SRC_DMA to complete */
209 	while ((CSUDMA_SRC_I_STS & CSUDMA_I_STS_DONE_MASK) != CSUDMA_I_STS_DONE_MASK) {
210 	};
211 
212 	/* acknowledge the transfer has completed */
213 	CSUDMA_SRC_I_STS = CSUDMA_I_STS_DONE_MASK;
214 
215 	return 0;
216 }
217 
wait_for_done(void)218 static int wait_for_done(void)
219 {
220 	/* wait for PCAP PL_DONE */
221 	while ((PCAP_STATUS & PCAP_PL_DONE_MASK) != PCAP_PL_DONE_MASK) {
222 	};
223 
224 	PCAP_RESET = PCAP_RESET_MASK;
225 	power_up_fpga();
226 
227 	return 0;
228 }
229 
zynqmp_fpga_get_status(const struct device * dev)230 static enum FPGA_status zynqmp_fpga_get_status(const struct device *dev)
231 {
232 	ARG_UNUSED(dev);
233 
234 	if ((PCAP_STATUS & PCAP_PL_INIT_MASK) && (PCAP_STATUS & PCAP_PL_DONE_MASK)) {
235 		return FPGA_STATUS_ACTIVE;
236 	} else {
237 		return FPGA_STATUS_INACTIVE;
238 	}
239 }
240 
zynqmp_fpga_get_info(const struct device * dev)241 static const char *zynqmp_fpga_get_info(const struct device *dev)
242 {
243 	struct zynqmp_fpga_data *data = dev->data;
244 
245 	return data->FPGA_info;
246 }
247 
zynqmp_fpga_reset(const struct device * dev)248 static int zynqmp_fpga_reset(const struct device *dev)
249 {
250 	ARG_UNUSED(dev);
251 
252 	/* Reset PL */
253 	PCAP_PROG = PCAP_PROG_RESET_MASK;
254 	PCAP_PROG = ~PCAP_PROG_RESET_MASK;
255 
256 	while ((PCAP_STATUS & PCAP_CFG_RESET) != PCAP_CFG_RESET) {
257 	};
258 
259 	return 0;
260 }
261 
init_pcap(const struct device * dev)262 static int init_pcap(const struct device *dev)
263 {
264 	/* take PCAP out of Reset */
265 	PCAP_RESET = ~PCAP_RESET_MASK;
266 
267 	/* select PCAP mode and change PCAP to write mode */
268 	PCAP_CTRL = PCAP_PR_MASK;
269 	PCAP_RDWR = PCAP_WRITE_MASK;
270 
271 	power_up_fpga();
272 
273 	/* setup the SSS */
274 	CSU_SSS_CFG = PCAP_PCAP_SSS_MASK;
275 
276 	zynqmp_fpga_reset(dev);
277 
278 	/* wait for pl init */
279 	while ((PCAP_STATUS & PCAP_PL_INIT_MASK) != PCAP_PL_INIT_MASK) {
280 	};
281 
282 	return 0;
283 }
284 
zynqmp_fpga_load(const struct device * dev,uint32_t * image_ptr,uint32_t img_size)285 static int zynqmp_fpga_load(const struct device *dev, uint32_t *image_ptr,
286 			    uint32_t img_size)
287 {
288 	uint32_t *addr = parse_header(dev, image_ptr, &img_size);
289 
290 	if (addr == NULL) {
291 		LOG_ERR("Failed to read bitstream");
292 		return -EINVAL;
293 	}
294 
295 	for (int i = 0; i < (img_size / 4); i++) {
296 		*(BITSTREAM + i) = __bswap_32(*(addr + i));
297 	}
298 
299 	init_pcap(dev);
300 	csudma_transfer(img_size);
301 	wait_for_done();
302 
303 	return 0;
304 }
305 
zynqmp_fpga_init(const struct device * dev)306 static int zynqmp_fpga_init(const struct device *dev)
307 {
308 	/* turn on PCAP CLK */
309 	PCAP_CLK_CTRL = PCAP_CLK_CTRL | PCAP_CLKACT_MASK;
310 
311 	update_part_name(dev);
312 
313 	return 0;
314 }
315 
316 static struct zynqmp_fpga_data fpga_data;
317 
318 static const struct fpga_driver_api zynqmp_api = {
319 	.reset = zynqmp_fpga_reset,
320 	.load = zynqmp_fpga_load,
321 	.get_status = zynqmp_fpga_get_status,
322 	.get_info = zynqmp_fpga_get_info
323 };
324 
325 DEVICE_DT_INST_DEFINE(0, &zynqmp_fpga_init, NULL, &fpga_data, NULL,
326 	      POST_KERNEL, CONFIG_FPGA_INIT_PRIORITY, &zynqmp_api);
327