/*
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/zephyr.h>
#include <zephyr/sys/printk.h>
#include <zephyr/drivers/peci.h>
#include <soc.h>

#define TASK_STACK_SIZE         1024
#define PRIORITY                7

/* PECI Host address */
#define PECI_HOST_ADDR          0x30u
/* PECI Host bitrate 1Mbps */
#define PECI_HOST_BITRATE       1000u

#define PECI_CONFIGINDEX_TJMAX  16u
#define PECI_CONFIGHOSTID       0u
#define PECI_CONFIGPARAM        0u

#define PECI_SAFE_TEMP          72

static const struct device *peci_dev;
static bool peci_initialized;
static uint8_t tjmax;
static uint8_t rx_fcs;
static void monitor_temperature_func(void *dummy1, void *dummy2, void *dummy3);

static struct k_thread temp_id;
K_THREAD_STACK_DEFINE(temp_stack, TASK_STACK_SIZE);

int peci_ping(void)
{
	int ret;
	struct peci_msg packet;

	printk("%s\n", __func__);

	packet.addr = PECI_HOST_ADDR;
	packet.cmd_code = PECI_CMD_PING;
	packet.tx_buffer.buf = NULL;
	packet.tx_buffer.len = PECI_PING_WR_LEN;
	packet.rx_buffer.buf = NULL;
	packet.rx_buffer.len = PECI_PING_RD_LEN;

	ret = peci_transfer(peci_dev, &packet);
	if (ret) {
		printk("ping failed %d\n", ret);
		return ret;
	}

	return 0;
}

int peci_get_tjmax(uint8_t *tjmax)
{
	int ret;
	int retries = 3;
	uint8_t peci_resp;
	struct peci_msg packet;

	uint8_t peci_resp_buf[PECI_RD_PKG_LEN_DWORD+1];
	uint8_t peci_req_buf[] = { PECI_CONFIGHOSTID,
				PECI_CONFIGINDEX_TJMAX,
				PECI_CONFIGPARAM & 0x00FF,
				(PECI_CONFIGPARAM & 0xFF00) >> 8,
	};

	packet.tx_buffer.buf = peci_req_buf;
	packet.tx_buffer.len = PECI_RD_PKG_WR_LEN;
	packet.rx_buffer.buf = peci_resp_buf;
	packet.rx_buffer.len = PECI_RD_PKG_LEN_DWORD;

	do {
		rx_fcs = 0;
		packet.addr = PECI_HOST_ADDR;
		packet.cmd_code = PECI_CMD_RD_PKG_CFG0;

		ret = peci_transfer(peci_dev, &packet);

		for (int i = 0; i < PECI_RD_PKG_LEN_DWORD; i++) {
			printk("%02x\n", packet.rx_buffer.buf[i]);
		}

		peci_resp = packet.rx_buffer.buf[0];
		rx_fcs = packet.rx_buffer.buf[PECI_RD_PKG_LEN_DWORD];
		k_sleep(K_MSEC(1));
		printk("\npeci_resp %x\n", peci_resp);
		retries--;
	} while ((peci_resp != PECI_CC_RSP_SUCCESS) && (retries > 0));

	*tjmax = packet.rx_buffer.buf[3];

	return 0;
}

int peci_get_temp(int *temperature)
{
	int16_t raw_cpu_temp;
	int ret;
	struct peci_msg packet = {0};

	uint8_t peci_resp_buf[PECI_GET_TEMP_RD_LEN+1];

	rx_fcs = 0;
	packet.tx_buffer.buf = NULL;
	packet.tx_buffer.len = PECI_GET_TEMP_WR_LEN;
	packet.rx_buffer.buf = peci_resp_buf;
	packet.rx_buffer.len = PECI_GET_TEMP_RD_LEN;

	packet.addr = PECI_HOST_ADDR;
	packet.cmd_code = PECI_CMD_GET_TEMP0;

	ret = peci_transfer(peci_dev, &packet);
	if (ret) {
		printk("Get temp failed %d\n", ret);
		return ret;
	}

	rx_fcs = packet.rx_buffer.buf[PECI_GET_TEMP_RD_LEN];
	printk("R FCS %x\n", rx_fcs);
	printk("Temp bytes: %02x", packet.rx_buffer.buf[0]);
	printk("%02x\n", packet.rx_buffer.buf[1]);

	raw_cpu_temp = (int16_t)(packet.rx_buffer.buf[0] |
			(int16_t)((packet.rx_buffer.buf[1] << 8) & 0xFF00));

	if (raw_cpu_temp == 0x8000) {
		printk("Invalid temp %x\n", raw_cpu_temp);
		*temperature = PECI_SAFE_TEMP;
		return -1;
	}

	raw_cpu_temp = (raw_cpu_temp >> 6) | 0x7E00;
	*temperature = raw_cpu_temp + tjmax;

	return 0;
}

void read_temp(void)
{
	int ret;
	int temp;

	ret = peci_get_temp(&temp);

	if (!ret) {
		printk("Temperature %d C\n", temp);
	}
}

void get_max_temp(void)
{
	int ret;

	ret = peci_get_tjmax(&tjmax);
	if (ret) {
		printk("Fail to obtain maximum temperature: %d\n", ret);
	} else {
		printk("Maximum temperature: %u\n", tjmax);
	}
}

static void monitor_temperature_func(void *dummy1, void *dummy2, void *dummy3)
{
	while (true) {
		k_sleep(K_MSEC(1000));
		if (peci_initialized) {
			read_temp();
		}
	}
}

void main(void)
{
#if DT_NODE_HAS_STATUS(DT_ALIAS(peci_0), okay)
	int ret;
#endif

	printk("PECI sample test\n");

	k_thread_create(&temp_id, temp_stack, TASK_STACK_SIZE,
		monitor_temperature_func, NULL, NULL, NULL, PRIORITY,
		K_INHERIT_PERMS, K_FOREVER);

#if DT_NODE_HAS_STATUS(DT_ALIAS(peci_0), okay)
	peci_dev = DEVICE_DT_GET(DT_ALIAS(peci_0));
	if (!device_is_ready(peci_dev)) {
		printk("Err: PECI device is not ready\n");
		return;
	}

	ret = peci_config(peci_dev, 1000u);
	if (ret) {
		printk("Err: Fail to configure bitrate\n");
		return;
	}

	peci_enable(peci_dev);

	tjmax = 100;

	get_max_temp();
	printk("Start thread...\n");
	k_thread_start(&temp_id);

	peci_initialized = true;
#endif
}
