1 /*
2  * Copyright (c) 2024 Microchip Technology Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT microchip_mpfs_mailbox
8 #include <stdio.h>
9 #include <string.h>
10 #include <zephyr/device.h>
11 #include <zephyr/devicetree.h>
12 #include <zephyr/drivers/flash.h>
13 #include <zephyr/drivers/fpga.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/logging/log.h>
16 #include <zephyr/sys/sys_io.h>
17 #include <zephyr/sys/util.h>
18 LOG_MODULE_REGISTER(fpga_mpfs, CONFIG_FPGA_LOG_LEVEL);
19 
20 #define SPI_FLASH_DIRECTORY_OFFSET    0x00000000
21 #define SPI_FLASH_GOLDEN_IMAGE_OFFSET 0x00100400
22 #define SPI_FLASH_NEW_IMAGE_OFFSET    0x01500400
23 #define SPI_FLASH_SECTOR_SIZE         4096
24 #define SPI_FLASH_PAGE_SIZE           256
25 
26 #define SERVICES_CR_OFFSET 0x50u
27 #define SERVICES_SR_OFFSET 0x54u
28 
29 #define SCBCTRL_SERVICESCR_REQ      (0u)
30 #define SCBCTRL_SERVICESCR_REQ_MASK BIT(SCBCTRL_SERVICESCR_REQ)
31 
32 #define SCBCTRL_SERVICESSR_BUSY      (1u)
33 #define SCBCTRL_SERVICESSR_BUSY_MASK BIT(SCBCTRL_SERVICESSR_BUSY)
34 
35 #define SCBCTRL_SERVICESSR_STATUS            (16u)
36 #define SCBCTRL_SERVICESSR_STATUS_MASK_WIDTH (16u)
37 #define SCBCTRL_SERVICESSR_STATUS_MASK                                                             \
38 	GENMASK(SCBCTRL_SERVICESSR_STATUS + SCBCTRL_SERVICESSR_STATUS_MASK_WIDTH - 1,              \
39 		SCBCTRL_SERVICESSR_STATUS)
40 
41 #define MSS_DESIGN_INFO_CMD                (0x02)
42 #define MSS_SYS_BITSTREAM_AUTHENTICATE_CMD 0x23u
43 #define MSS_SYS_IAP_PROGRAM_BY_SPIIDX_CMD  0x42u
44 
45 struct mpfs_fpga_config {
46 	mm_reg_t base;
47 	mm_reg_t mailbox;
48 };
49 
50 struct mpfs_fpga_data {
51 	char FPGA_design_ver[30];
52 };
53 
scb_read(mm_reg_t add,mm_reg_t offset)54 static inline uint32_t scb_read(mm_reg_t add, mm_reg_t offset)
55 {
56 	return sys_read32(add + offset);
57 }
58 
scb_write(mm_reg_t add,mm_reg_t offset,uint32_t val)59 static inline void scb_write(mm_reg_t add, mm_reg_t offset, uint32_t val)
60 {
61 	sys_write32(val, add + offset);
62 }
63 
64 /*This function add the index of new image into the spi directory at offset 0x004.
65  * Note: In the Flash directory first four pages(each page of 256 Bytes) have either
66  * a valid image address or zeros. The other remaining 12 pages are all filled with 0xFFs.
67  *
68  * |------------------------------| 0x000
69  * | Golden Image Address:        |
70  * | 0x0100400                    |
71  * |------------------------------| 0x004
72  * | Update Image Address         |
73  * | 0x1500400                    |
74  * |------------------------------| 0x008
75  * | Empty                        |
76  * | 0x000000                     |
77  * |------------------------------| 0x00C
78  * | Unused for re-programming    |
79  * |                              |
80  * |------------------------------| 0x400
81  */
update_spi_flash_directory(const struct device * flash_dev)82 static uint8_t update_spi_flash_directory(const struct device *flash_dev)
83 {
84 	size_t len = SPI_FLASH_PAGE_SIZE;
85 	uint8_t buf[SPI_FLASH_PAGE_SIZE];
86 	uint8_t rc, k;
87 
88 	memset(buf, 0, len);
89 
90 	rc = flash_read(flash_dev, SPI_FLASH_DIRECTORY_OFFSET, buf, len);
91 	if (rc != 0) {
92 		LOG_ERR("Flash read failed! %d", rc);
93 		return rc;
94 	}
95 
96 	/* New image address(0x1500400) entry at offset 0x004 */
97 	buf[4] = 0x00;
98 	buf[5] = 0x04;
99 	buf[6] = 0x50;
100 	buf[7] = 0x01;
101 
102 	/* Erase SPI flash directory */
103 
104 	rc = flash_erase(flash_dev, SPI_FLASH_DIRECTORY_OFFSET, SPI_FLASH_SECTOR_SIZE);
105 	if (rc != 0) {
106 		LOG_ERR("erase failed! %d", rc);
107 	}
108 
109 	/* Write the first page with updated address entry */
110 	rc = flash_write(flash_dev, SPI_FLASH_DIRECTORY_OFFSET, buf, len);
111 	if (rc != 0) {
112 		LOG_ERR("Flash write failed! %d", rc);
113 		return rc;
114 	}
115 
116 	/* Fill page number second, third and fourth with zeros */
117 	memset(buf, 0, len);
118 	k = 1;
119 	while (k < 4) {
120 		rc = flash_write(flash_dev, (SPI_FLASH_DIRECTORY_OFFSET + k * 0x100), buf, len);
121 		if (rc != 0) {
122 			LOG_ERR("Flash write failed! %d", rc);
123 			return rc;
124 		}
125 		k++;
126 	}
127 
128 	return rc;
129 }
130 
131 /* This function Program a new FPGA design image into the SPI Flash at location
132  * 0x1500400.
133  * Note: The source location of new image is _bin_start symbol value and the size of
134  * new image is  _bim_size symbol value.
135  */
program_new_image(const struct device * flash_dev,uint8_t * image_start,uint32_t image_size)136 static uint8_t program_new_image(const struct device *flash_dev, uint8_t *image_start,
137 				 uint32_t image_size)
138 {
139 	size_t len = SPI_FLASH_PAGE_SIZE;
140 	uint8_t buf[SPI_FLASH_PAGE_SIZE];
141 	uint8_t rc;
142 	uint32_t i, count, k;
143 	uint8_t *temp;
144 
145 	temp = image_start;
146 
147 	if (image_size > 0x1400000) {
148 		LOG_ERR("Image is larger than 20Mb");
149 		return 1;
150 	}
151 
152 	/* Find the sectors to erase */
153 	count = (uint32_t)(image_size / SPI_FLASH_SECTOR_SIZE) + 1;
154 
155 	LOG_INF("Erasing.");
156 	i = 0;
157 	while (i < count) {
158 		rc = flash_erase(
159 			flash_dev,
160 			((SPI_FLASH_NEW_IMAGE_OFFSET - 0x400) + (i * SPI_FLASH_SECTOR_SIZE)),
161 			SPI_FLASH_SECTOR_SIZE);
162 		if (rc != 0) {
163 			LOG_ERR("erase failed! %d", rc);
164 		}
165 
166 		if (i % 0x100 == 0) {
167 			LOG_DBG(".");
168 		}
169 
170 		i++;
171 	}
172 	/* Erase completed and ready to program new image */
173 
174 	/* Find the pages to program */
175 	count = (uint32_t)(image_size / SPI_FLASH_PAGE_SIZE) + 1;
176 
177 	LOG_INF("Programming.");
178 	i = 0;
179 	while (i < count) {
180 		temp = (image_start + i * SPI_FLASH_PAGE_SIZE);
181 		memset(buf, 0, len);
182 		for (k = 0; k < 256; k++) {
183 			buf[k] = *temp;
184 			temp = temp + 1;
185 		}
186 
187 		rc = flash_write(flash_dev, (SPI_FLASH_NEW_IMAGE_OFFSET + i * SPI_FLASH_PAGE_SIZE),
188 				 buf, len);
189 		if (rc != 0) {
190 			LOG_ERR("Flash write failed! %d", rc);
191 			return rc;
192 		}
193 
194 		if (i % 0x100 == 0) {
195 			LOG_DBG(".");
196 		}
197 
198 		i++;
199 	}
200 
201 	LOG_INF("Programming completed.");
202 
203 	return rc;
204 }
205 
verify_image(const struct device * dev)206 static int8_t verify_image(const struct device *dev)
207 {
208 	const struct mpfs_fpga_config *cfg = dev->config;
209 	int8_t status = EINVAL;
210 	uint32_t value = 0;
211 
212 	LOG_INF("Image verification started...");
213 
214 	/* Once system controller starts processing command The busy bit will
215 	 * go 1. Make sure that service is complete i.e. BUSY bit is gone 0
216 	 */
217 	while (scb_read(cfg->base, SERVICES_SR_OFFSET) & SCBCTRL_SERVICESSR_BUSY_MASK) {
218 		;
219 	}
220 
221 	/* Form the SS command: bit 0 to 6 is the opcode, bit 7 to 15 is the Mailbox
222 	 * offset For some services this field has another meaning.
223 	 * (e.g. for IAP bit-stream auth. it means spi_idx)
224 	 */
225 	scb_write(cfg->mailbox, 0, 0x1500400);
226 
227 	value = (MSS_SYS_BITSTREAM_AUTHENTICATE_CMD << 16) | 0x1;
228 	scb_write(cfg->base, SERVICES_CR_OFFSET, value);
229 
230 	/* REQ bit will remain set till the system controller starts
231 	 * processing command. Since DRI is slow interface, we are waiting
232 	 * here to make sure System controller has started processing
233 	 * command
234 	 */
235 	while (scb_read(cfg->base, SERVICES_CR_OFFSET) & SCBCTRL_SERVICESCR_REQ_MASK) {
236 		;
237 	}
238 
239 	/* Once system controller starts processing command The busy bit will
240 	 * go 1. Make sure that service is complete i.e. BUSY bit is gone 0
241 	 */
242 	while (scb_read(cfg->base, SERVICES_SR_OFFSET) & SCBCTRL_SERVICESSR_BUSY_MASK) {
243 		;
244 	}
245 
246 	/* Read the status returned by System Controller */
247 	status = ((scb_read(cfg->base, SERVICES_SR_OFFSET) & SCBCTRL_SERVICESSR_STATUS_MASK) >>
248 		  SCBCTRL_SERVICESSR_STATUS);
249 	LOG_INF("Image verification status  : %x   ", status);
250 
251 	return status;
252 }
253 
activate_image(const struct device * dev)254 static void activate_image(const struct device *dev)
255 {
256 	const struct mpfs_fpga_config *cfg = dev->config;
257 	int8_t status = EINVAL;
258 	uint32_t value = 0;
259 
260 	LOG_INF("Image activation started...");
261 
262 	/* Once system controller starts processing command The busy bit will
263 	 * go 1. Make sure that service is complete i.e. BUSY bit is gone 0
264 	 */
265 	while (scb_read(cfg->base, SERVICES_SR_OFFSET) & SCBCTRL_SERVICESSR_BUSY_MASK) {
266 		;
267 	}
268 
269 	/* Form the SS command: bit 0 to 6 is the opcode, bit 7 to 15 is the Mailbox
270 	 * offset For some services this field has another meaning.
271 	 * (e.g. for IAP bit-stream auth. it means spi_idx)
272 	 */
273 	value = (MSS_SYS_IAP_PROGRAM_BY_SPIIDX_CMD << 16) | BIT(23) | 0x1;
274 	scb_write(cfg->base, SERVICES_CR_OFFSET, value);
275 
276 	/* REQ bit will remain set till the system controller starts
277 	 * processing command. Since DRI is slow interface, we are waiting
278 	 * here to make sure System controller has started processing
279 	 * command
280 	 */
281 	while (scb_read(cfg->base, SERVICES_CR_OFFSET) & SCBCTRL_SERVICESCR_REQ_MASK) {
282 		;
283 	}
284 
285 	/* Once system controller starts processing command The busy bit will
286 	 * go 1. Make sure that service is complete i.e. BUSY bit is gone 0
287 	 */
288 	while (scb_read(cfg->base, SERVICES_SR_OFFSET) & SCBCTRL_SERVICESSR_BUSY_MASK) {
289 		;
290 	}
291 
292 	/* Read the status returned by System Controller */
293 	status = ((scb_read(cfg->base, SERVICES_SR_OFFSET) & SCBCTRL_SERVICESSR_STATUS_MASK) >>
294 		  SCBCTRL_SERVICESSR_STATUS);
295 	LOG_INF("Image activation status  : %x   ", status);
296 }
297 
mpfs_fpga_reset(const struct device * dev)298 static int mpfs_fpga_reset(const struct device *dev)
299 {
300 	int8_t status = EINVAL;
301 
302 	status = verify_image(dev);
303 	if (status == 0) {
304 		activate_image(dev);
305 	}
306 	return 0;
307 }
308 
mpfs_fpga_load(const struct device * dev,uint32_t * image_ptr,uint32_t img_size)309 static int mpfs_fpga_load(const struct device *dev, uint32_t *image_ptr, uint32_t img_size)
310 {
311 	const struct device *flash_dev = DEVICE_DT_GET_OR_NULL(DT_ALIAS(bitstream_flash));
312 
313 	if (flash_dev == NULL) {
314 		LOG_ERR("Device not found");
315 		return -ENOENT;
316 	}
317 
318 	if (!device_is_ready(flash_dev)) {
319 		LOG_ERR("%s: device not ready.", flash_dev->name);
320 		return 1;
321 	}
322 
323 	if (img_size == 0) {
324 		LOG_ERR("Image size is zero.");
325 		return -EINVAL;
326 	}
327 
328 	if (image_ptr == NULL) {
329 		LOG_ERR("Failed to read FPGA image");
330 		return -EINVAL;
331 	}
332 
333 	update_spi_flash_directory(flash_dev);
334 	program_new_image(flash_dev, (uint8_t *)image_ptr, img_size);
335 	return 0;
336 }
337 
mpfs_fpga_get_info(const struct device * dev)338 static const char *mpfs_fpga_get_info(const struct device *dev)
339 {
340 	struct mpfs_fpga_data *data = dev->data;
341 	const struct mpfs_fpga_config *cfg = dev->config;
342 	uint32_t value = 0;
343 	uint16_t design_version = 0;
344 
345 	/* Once system controller starts processing command The busy bit will
346 	 * go 1. Make sure that service is complete i.e. BUSY bit is gone 0
347 	 */
348 	while (scb_read(cfg->base, SERVICES_SR_OFFSET) & SCBCTRL_SERVICESSR_BUSY_MASK) {
349 		;
350 	}
351 
352 	/* Form the SS command: bit 0 to 6 is the opcode, bit 7 to 15 is the Mailbox
353 	 * offset For some services this field has another meaning.
354 	 * (e.g. for IAP bit-stream auth. it means spi_idx)
355 	 */
356 
357 	value = (MSS_DESIGN_INFO_CMD << 16) | 0x1;
358 	scb_write(cfg->base, SERVICES_CR_OFFSET, value);
359 
360 	/* REQ bit will remain set till the system controller starts
361 	 * processing command. Since DRI is slow interface, we are waiting
362 	 * here to make sure System controller has started processing
363 	 * command
364 	 */
365 	while (scb_read(cfg->base, SERVICES_CR_OFFSET) & SCBCTRL_SERVICESCR_REQ_MASK) {
366 		;
367 	}
368 
369 	/* Once system controller starts processing command The busy bit will
370 	 * go 1. Make sure that service is complete i.e. BUSY bit is gone 0
371 	 */
372 	while (scb_read(cfg->base, SERVICES_SR_OFFSET) & SCBCTRL_SERVICESSR_BUSY_MASK) {
373 		;
374 	}
375 
376 	design_version = scb_read(cfg->mailbox, 32);
377 	sprintf(data->FPGA_design_ver, (uint8_t *)"Design Version : 0x%x", design_version);
378 
379 	return data->FPGA_design_ver;
380 }
381 
mpfs_fpga_get_status(const struct device * dev)382 static enum FPGA_status mpfs_fpga_get_status(const struct device *dev)
383 {
384 	const struct mpfs_fpga_config *cfg = dev->config;
385 
386 	if (scb_read(cfg->base, SERVICES_SR_OFFSET) & SCBCTRL_SERVICESSR_BUSY_MASK) {
387 		return FPGA_STATUS_INACTIVE;
388 	} else {
389 		return FPGA_STATUS_ACTIVE;
390 	}
391 }
392 
mpfs_fpga_init(const struct device * dev)393 static int mpfs_fpga_init(const struct device *dev)
394 {
395 	return 0;
396 }
397 
398 static struct mpfs_fpga_data fpga_data;
399 
400 static struct mpfs_fpga_config fpga_config = {
401 	.base = DT_INST_REG_ADDR_BY_IDX(0, 0),
402 	.mailbox = DT_INST_REG_ADDR_BY_IDX(0, 2),
403 };
404 
405 static DEVICE_API(fpga, mpfs_fpga_api) = {
406 	.reset = mpfs_fpga_reset,
407 	.load = mpfs_fpga_load,
408 	.get_info = mpfs_fpga_get_info,
409 	.get_status = mpfs_fpga_get_status,
410 };
411 
412 DEVICE_DT_INST_DEFINE(0, &mpfs_fpga_init, NULL, &fpga_data, &fpga_config, POST_KERNEL,
413 		      CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &mpfs_fpga_api);
414