/*
 * Copyright (c) 2022 Microchip Technology Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <errno.h>
#include <zephyr/device.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/mchp_xec_clock_control.h>
#include <zephyr/dt-bindings/clock/mchp_xec_pcr.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/printk.h>
LOG_MODULE_REGISTER(clock32k, CONFIG_CLOCK_CONTROL_LOG_LEVEL);

#include <soc.h>

#ifdef CONFIG_SOC_SERIES_MEC1501X
static void pcr_clock_regs(void)
{
	struct pcr_regs *pcr = ((struct pcr_regs *)DT_REG_ADDR_BY_IDX(DT_NODELABEL(pcr), 0));
	uint32_t r = pcr->PWR_RST_STS;

	LOG_INF("MEC152x PCR registers");

	LOG_INF("PCR Power Reset Status register(bit[10] is 32K_ACTIVE) = 0x%x", r);

	r = pcr->OSC_ID;
	LOG_INF("PCR Oscillator ID register(bit[8]=PLL Lock) = 0x%x", r);

	r = pcr->PROC_CLK_CTRL;
	LOG_INF("PCR Processor Clock Control register = 0x%x", r);

	r = pcr->SLOW_CLK_CTRL;
	LOG_INF("PCR Slow Clock Control register = 0x%x", r);
}

static void vbat_clock_regs(void)
{
	struct vbatr_regs *vbr = ((struct vbatr_regs *)DT_REG_ADDR_BY_IDX(DT_NODELABEL(pcr), 1));
	uint32_t cken = vbr->CLK32_EN;

	LOG_INF("MEC152x VBAT Clock registers");
	LOG_INF("ClockEnable = 0x%08x", cken);
	if (cken & BIT(2)) {
		LOG_INF("32KHz clock source is XTAL");
		if (cken & BIT(3)) {
			LOG_INF("XTAL configured for single-ended using XTAL2 pin"
				" (external 32KHz waveform)");
		} else {
			LOG_INF("XTAL configured for parallel resonant crystal circuit on"
				" XTAL1 and XTAL2 pins");
		}
	} else {
		LOG_INF("32KHz clock source is the Internal Silicon 32KHz OSC");
	}
	if (cken & BIT(1)) {
		LOG_INF("32KHz clock domain uses the 32KHZ_IN pin(GPIO_0165 F1)");
	} else {
		LOG_INF("32KHz clock domain uses the 32KHz clock source");
	}

	LOG_INF("32KHz trim = 0x%08x", vbr->CKK32_TRIM);
}

static void vbat_power_fail(void)
{
	struct vbatr_regs *vbr = ((struct vbatr_regs *)DT_REG_ADDR_BY_IDX(DT_NODELABEL(pcr), 1));
	uint32_t pfrs = vbr->PFRS;

	LOG_INF("MEC152x VBAT Power-Fail-Reset-Status = 0x%x", pfrs);

	if (pfrs & MCHP_VBATR_PFRS_VBAT_RST_POS) {
		LOG_INF("WARNING: VBAT POR. Clock control register settings lost during"
			" power cycle");
	}

	vbr->PFRS = 0xffffffffU;
}
#else
static void print_pll_clock_src(uint32_t pcr_clk_src)
{
	uint32_t temp = pcr_clk_src & MCHP_PCR_VTR_32K_SRC_MASK;

	if (temp == MCHP_PCR_VTR_32K_SRC_SILOSC) {
		LOG_INF("PLL 32K clock source is Internal Silicon OSC(VTR)");
	} else if (temp == MCHP_PCR_VTR_32K_SRC_XTAL) {
		LOG_INF("PLL 32K clock source is XTAL input(VTR)");
	} else if (temp == MCHP_PCR_VTR_32K_SRC_PIN) {
		LOG_INF("PLL 32K clock source is 32KHZ_IN pin(VTR)");
	} else {
		LOG_INF("PLL 32K clock source is OFF. PLL disabled. Running on Ring OSC");
	}
}

static void print_periph_clock_src(uint32_t vb_clk_src)
{
	uint32_t temp = (vb_clk_src & MCHP_VBATR_CS_PCS_MSK) >> MCHP_VBATR_CS_PCS_POS;

	if (temp == MCHP_VBATR_CS_PCR_VTR_VBAT_SO_VAL) {
		LOG_INF("Periph 32K clock source is InternalOSC(VTR) and InternalOSC(VBAT)");
	} else if (temp == MCHP_VBATR_CS_PCS_VTR_VBAT_XTAL_VAL) {
		LOG_INF("Periph 32K clock source is XTAL(VTR) and XTAL(VBAT)");
	} else if (temp == MCHP_VBATR_CS_PCS_VTR_PIN_SO_VAL) {
		LOG_INF("Periph 32K clock source is 32KHZ_PIN(VTR) and InternalOSC(VBAT)");
	} else {
		LOG_INF("Periph 32K clock source is 32KHZ_PIN fallback to XTAL when VTR is off");
	}
}

static void pcr_clock_regs(void)
{
	struct pcr_regs *pcr = ((struct pcr_regs *)DT_REG_ADDR_BY_IDX(DT_NODELABEL(pcr), 0));
	uint32_t pcr_clk_src = pcr->CLK32K_SRC_VTR;
	uint32_t r = pcr->PWR_RST_STS;

	LOG_INF("MEC172x PCR registers");

	print_pll_clock_src(pcr_clk_src);

	LOG_INF("PCR Power Reset Status register(b[10] is 32K_ACTIVE) = 0x%x", r);

	r = pcr->OSC_ID;
	LOG_INF("PCR Oscillator ID register(bit[8]=PLL Lock) = 0x%x", r);

	r = pcr->PROC_CLK_CTRL;
	LOG_INF("PCR Processor Clock Control register = 0x%x", r);

	r = pcr->SLOW_CLK_CTRL;
	LOG_INF("PCR Slow Clock Control register = 0x%x", r);

	r = pcr->CNT32K_PER;
	LOG_INF("PCR 32KHz Clock Monitor Pulse High Count register = 0x%x", r);

	r = pcr->CNT32K_PER_MIN;
	LOG_INF("PCR 32KHz Clock Monitor Period Maximum Count register = 0x%x", r);

	r = pcr->CNT32K_DV;
	LOG_INF("PCR 32KHz Clock Monitor Duty Cycle Variation register = 0x%x", r);

	r = pcr->CNT32K_DV_MAX;
	LOG_INF("PCR 32KHz Clock Monitor Duty Cycle Variation Max register = 0x%x", r);

	r = pcr->CNT32K_VALID;
	LOG_INF("PCR 32KHz Clock Monitor Valid register = 0x%x", r);

	r = pcr->CNT32K_VALID_MIN;
	LOG_INF("PCR 32KHz Clock Monitor Valid Min register = 0x%x", r);

	r = pcr->CNT32K_CTRL;
	LOG_INF("PCR 32KHz Clock Monitor Control register = 0x%x", r);

	r = pcr->CLK32K_MON_ISTS;
	LOG_INF("PCR 32KHz Clock Monitor Control Status register = 0x%x", r);
}

static void vbat_clock_regs(void)
{
	struct vbatr_regs *vbr = ((struct vbatr_regs *)DT_REG_ADDR_BY_IDX(DT_NODELABEL(pcr), 1));
	uint32_t vb_clk_src = vbr->CLK32_SRC;

	print_periph_clock_src(vb_clk_src);
}

static void vbat_power_fail(void)
{
	struct vbatr_regs *vbr = ((struct vbatr_regs *)DT_REG_ADDR_BY_IDX(DT_NODELABEL(pcr), 1));
	uint32_t pfrs = vbr->PFRS;

	LOG_INF("MEC172x VBAT Power-Fail-Reset-Status = 0x%x", pfrs);

	if (pfrs & MCHP_VBATR_PFRS_VBAT_RST_POS) {
		LOG_INF("WARNING: VBAT POR. Clock control register settings"
			" lost during power cycle");
	}

	/* clear VBAT powered status */
	vbr->PFRS = 0xffffffffU;
}
#endif

static const struct gpio_ctrl_regs * const gpc =
	(struct gpio_ctrl_regs *)(DT_REG_ADDR(DT_NODELABEL(gpio_000_036)));
static const struct device *clkdev = DEVICE_DT_GET(DT_NODELABEL(pcr));

struct sys_clk {
	uint32_t id;
	char *name;
};

static const struct sys_clk sys_clocks[] = {
	{ .id = MCHP_XEC_PCR_CLK_CORE, .name = "Core" },
	{ .id = MCHP_XEC_PCR_CLK_CPU, .name = "CPU" },
	{ .id = MCHP_XEC_PCR_CLK_BUS, .name = "Bus" },
	{ .id = MCHP_XEC_PCR_CLK_PERIPH, .name = "Periph" },
	{ .id = MCHP_XEC_PCR_CLK_PERIPH_FAST, .name = "Periph-fast" },
	{ .id = MCHP_XEC_PCR_CLK_PERIPH_SLOW, .name = "Periph-slow" },
};

int main(void)
{
	int rc = 0;
	uint32_t rate = 0U;
	uint32_t r = 0U;
	clock_control_subsys_t sys = NULL;

	LOG_INF("XEC Clock control driver sample");

	if (!device_is_ready(clkdev)) {
		LOG_ERR("XEC clock control driver is not ready!");
		return 0;
	}

	vbat_power_fail();

	LOG_INF("32KHZ_IN is function 1 of GPIO 0165");
	r = gpc->CTRL_0165;
	LOG_INF("XEC GPIO 0165 Control = 0x%x", gpc->CTRL_0165);
	r = (r & MCHP_GPIO_CTRL_MUX_MASK) >> MCHP_GPIO_CTRL_MUX_POS;
	LOG_INF("Pin function = %u", r);
	vbat_clock_regs();
	pcr_clock_regs();

	for (size_t i = 0; i < ARRAY_SIZE(sys_clocks); i++) {
		LOG_INF("API get rate for %s", sys_clocks[i].name);
		sys = (clock_control_subsys_t)sys_clocks[i].id;
		rate = 0U;
		rc = clock_control_get_rate(clkdev, sys, &rate);
		if (rc) {
			LOG_ERR("API error: %d", rc);
		} else {
			LOG_INF("rate = %u", rate);
		}
	}
	return 0;
}
