/*
 * Copyright (c) 2021-2022 Antmicro <www.antmicro.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT xlnx_fpga

#include <zephyr/device.h>
#include <zephyr/drivers/fpga.h>
#include "fpga_zynqmp.h"
#include <errno.h>
#include <string.h>
#include <zephyr/sys/byteorder.h>
#include <stdlib.h>
#include <stdio.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(fpga_zynqmp, CONFIG_FPGA_LOG_LEVEL);

static void power_up_fpga(void)
{
	PMU_GLOBAL_PWRUP_EN = PWR_PL_MASK;
	PMU_REQ_PWRUP_TRIG = PWR_PL_MASK;

	while (PWR_STATUS & PWR_PL_MASK) {
	};
}

struct zynqmp_fpga_data {
	char FPGA_info[16];
};

static void update_part_name(const struct device *dev)
{
	struct zynqmp_fpga_data *data = dev->data;

	int zu_number = 0;

	switch (IDCODE & IDCODE_MASK) {
	case ZU2_IDCODE:
		zu_number = 2;
		break;
	case ZU3_IDCODE:
		zu_number = 3;
		break;
	case ZU4_IDCODE:
		zu_number = 4;
		break;
	case ZU5_IDCODE:
		zu_number = 5;
		break;
	case ZU6_IDCODE:
		zu_number = 6;
		break;
	case ZU7_IDCODE:
		zu_number = 7;
		break;
	case ZU9_IDCODE:
		zu_number = 9;
		break;
	case ZU11_IDCODE:
		zu_number = 11;
		break;
	case ZU15_IDCODE:
		zu_number = 15;
		break;
	case ZU17_IDCODE:
		zu_number = 17;
		break;
	case ZU19_IDCODE:
		zu_number = 19;
		break;
	case ZU21_IDCODE:
		zu_number = 21;
		break;
	case ZU25_IDCODE:
		zu_number = 25;
		break;
	case ZU27_IDCODE:
		zu_number = 27;
		break;
	case ZU28_IDCODE:
		zu_number = 28;
		break;
	case ZU29_IDCODE:
		zu_number = 29;
		break;
	case ZU39_IDCODE:
		zu_number = 39;
		break;
	case ZU43_IDCODE:
		zu_number = 43;
		break;
	case ZU46_IDCODE:
		zu_number = 46;
		break;
	case ZU47_IDCODE:
		zu_number = 47;
		break;
	case ZU48_IDCODE:
		zu_number = 48;
		break;
	case ZU49_IDCODE:
		zu_number = 49;
		break;
	}

	if (zu_number == 0) {
		snprintf(data->FPGA_info, sizeof(data->FPGA_info), "unknown");
	} else {
		snprintf(data->FPGA_info, sizeof(data->FPGA_info), "Part name: ZU%d", zu_number);
	}

}

/*
 * This function is responsible for shifting the bitstream
 * by its header and extracting information from this header.
 * The bitstream header has 5 sections starting with the letters a,b,c...
 * Each section has the following structure:
 * [key][length of data][data]
 */
static uint32_t *parse_header(const struct device *dev, uint32_t *image_ptr,
		       uint32_t *img_size)
{
	unsigned char *header = (unsigned char *)image_ptr;

	uint32_t length = XLNX_BITSTREAM_SECTION_LENGTH(header);

	/* shift to the next section*/
	header += 0x4U + length;

	if (*header++ != 'a') {
		LOG_ERR("Incorrect bitstream format");
		return NULL;
	}

	length = XLNX_BITSTREAM_SECTION_LENGTH(header);
	/* shift to the data section*/
	header += 0x2U;

	LOG_DBG("Design name = %s", header);

	header += length;

	if (*header++ != 'b') {
		LOG_ERR("Incorrect bitstream format");
		return NULL;
	}

	length = XLNX_BITSTREAM_SECTION_LENGTH(header);
	/* shift to the data section*/
	header += 0x2U;
	LOG_DBG("Part name = %s", header);

	header += length;

	if (*header++ != 'c') {
		LOG_ERR("Incorrect bitstream format");
		return NULL;
	}

	length = XLNX_BITSTREAM_SECTION_LENGTH(header);
	/* shift to the data section*/
	header += 0x2U;

	LOG_DBG("Date =  %s", header);

	header += length;

	if (*header++ != 'd') {
		LOG_ERR("Incorrect bitstream format");
		return NULL;
	}

	length = XLNX_BITSTREAM_SECTION_LENGTH(header);
	/* shift to the data section*/
	header += 0x2U;

	LOG_DBG("Time =  %s", header);

	header += length;

	if (*header++ != 'e') {
		LOG_ERR("Incorrect bitstream format");
		return NULL;
	}

	/*
	 * The last section is the raw bitstream.
	 * It is preceded by its size, which is needed for DMA transfer.
	 */
	*img_size =
		((uint32_t)*header << 24) | ((uint32_t) *(header + 1) << 16) |
		((uint32_t) *(header + 2) << 8) | ((uint32_t) *(header + 3));

	return (uint32_t *)header;
}

static int csudma_transfer(uint32_t size)
{
	/* setup the source DMA channel */
	CSUDMA_SRC_ADDR = (uint32_t)BITSTREAM & CSUDMA_SRC_ADDR_MASK;
	CSUDMA_SRC_ADDR_MSB = 0;
	CSUDMA_SRC_SIZE = size << CSUDMA_SRC_SIZE_SHIFT;

	/* wait for the SRC_DMA to complete */
	while ((CSUDMA_SRC_I_STS & CSUDMA_I_STS_DONE_MASK) != CSUDMA_I_STS_DONE_MASK) {
	};

	/* acknowledge the transfer has completed */
	CSUDMA_SRC_I_STS = CSUDMA_I_STS_DONE_MASK;

	return 0;
}

static int wait_for_done(void)
{
	/* wait for PCAP PL_DONE */
	while ((PCAP_STATUS & PCAP_PL_DONE_MASK) != PCAP_PL_DONE_MASK) {
	};

	PCAP_RESET = PCAP_RESET_MASK;
	power_up_fpga();

	return 0;
}

static enum FPGA_status zynqmp_fpga_get_status(const struct device *dev)
{
	ARG_UNUSED(dev);

	if ((PCAP_STATUS & PCAP_PL_INIT_MASK) && (PCAP_STATUS & PCAP_PL_DONE_MASK)) {
		return FPGA_STATUS_ACTIVE;
	} else {
		return FPGA_STATUS_INACTIVE;
	}
}

static const char *zynqmp_fpga_get_info(const struct device *dev)
{
	struct zynqmp_fpga_data *data = dev->data;

	return data->FPGA_info;
}

static int zynqmp_fpga_reset(const struct device *dev)
{
	ARG_UNUSED(dev);

	/* Reset PL */
	PCAP_PROG = PCAP_PROG_RESET_MASK;
	PCAP_PROG = ~PCAP_PROG_RESET_MASK;

	while ((PCAP_STATUS & PCAP_CFG_RESET) != PCAP_CFG_RESET) {
	};

	return 0;
}

static int init_pcap(const struct device *dev)
{
	/* take PCAP out of Reset */
	PCAP_RESET = ~PCAP_RESET_MASK;

	/* select PCAP mode and change PCAP to write mode */
	PCAP_CTRL = PCAP_PR_MASK;
	PCAP_RDWR = PCAP_WRITE_MASK;

	power_up_fpga();

	/* setup the SSS */
	CSU_SSS_CFG = PCAP_PCAP_SSS_MASK;

	zynqmp_fpga_reset(dev);

	/* wait for pl init */
	while ((PCAP_STATUS & PCAP_PL_INIT_MASK) != PCAP_PL_INIT_MASK) {
	};

	return 0;
}

static int zynqmp_fpga_load(const struct device *dev, uint32_t *image_ptr,
			    uint32_t img_size)
{
	uint32_t *addr = parse_header(dev, image_ptr, &img_size);

	if (addr == NULL) {
		LOG_ERR("Failed to read bitstream");
		return -EINVAL;
	}

	for (int i = 0; i < (img_size / 4); i++) {
		*(BITSTREAM + i) = BSWAP_32(*(addr + i));
	}

	init_pcap(dev);
	csudma_transfer(img_size);
	wait_for_done();

	return 0;
}

static int zynqmp_fpga_init(const struct device *dev)
{
	/* turn on PCAP CLK */
	PCAP_CLK_CTRL = PCAP_CLK_CTRL | PCAP_CLKACT_MASK;

	update_part_name(dev);

	return 0;
}

static struct zynqmp_fpga_data fpga_data;

static DEVICE_API(fpga, zynqmp_api) = {
	.reset = zynqmp_fpga_reset,
	.load = zynqmp_fpga_load,
	.get_status = zynqmp_fpga_get_status,
	.get_info = zynqmp_fpga_get_info
};

DEVICE_DT_INST_DEFINE(0, &zynqmp_fpga_init, NULL, &fpga_data, NULL,
	      POST_KERNEL, CONFIG_FPGA_INIT_PRIORITY, &zynqmp_api);
