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

#include <zephyr/kernel.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 *const peci_dev = DEVICE_DT_GET(DT_ALIAS(peci_0));
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)
{
	int ret;

	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 (!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;
}
