/*
 * Copyright (c) 2019 STMicroelectronics.
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr.h>
#include <pm/pm.h>
#include <soc.h>
#include <init.h>

#include <stm32wbxx_ll_utils.h>
#include <stm32wbxx_ll_bus.h>
#include <stm32wbxx_ll_cortex.h>
#include <stm32wbxx_ll_pwr.h>
#include <stm32wbxx_ll_rcc.h>
#include <clock_control/clock_stm32_ll_common.h>
#include "stm32_hsem.h"

#include <bluetooth/hci.h>

#include <logging/log.h>
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);

/*
 * @brief Switch the system clock on HSI
 * @param none
 * @retval none
 */
static void switch_on_hsi(void)
{
	LL_RCC_HSI_Enable();
	while (!LL_RCC_HSI_IsReady()) {
	}

	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
	LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSI);
	while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
	}
}

static void lpm_hsem_lock(void)
{
	/* Implementation of STM32 AN5289 algorithm to enter/exit lowpower */
	z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_WAIT_FOREVER);

	if (!LL_HSEM_1StepLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID)) {
		if (LL_PWR_IsActiveFlag_C2DS()) {
			/* Release ENTRY_STOP_MODE semaphore */
			LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);

			/* The switch on HSI before entering Stop Mode is required */
			switch_on_hsi();
		}
	} else {
		/* The switch on HSI before entering Stop Mode is required */
		switch_on_hsi();
	}
}

#define ACI_HAL_STACK_RESET 0xFC3B

static void send_stack_reset(void)
{
	struct net_buf *rsp;
	int err = 0;

	err = bt_hci_cmd_send_sync(ACI_HAL_STACK_RESET, NULL, &rsp);

	net_buf_unref(rsp);

	if (err) {
		LOG_ERR("M0 BLE stack reset issue");
	}
}


static void shutdown_ble_stack(void)
{
	send_stack_reset();

	/* Wait till C2DS set */
	while (LL_PWR_IsActiveFlag_C2DS() == 0) {
	};
}

/* Invoke Low Power/System Off specific Tasks */
__weak void pm_power_state_set(struct pm_state_info info)
{
	if (info.state == PM_STATE_SOFT_OFF) {

		if (IS_ENABLED(CONFIG_BT)) {
			shutdown_ble_stack();
		}

		lpm_hsem_lock();

		/* Clear all Wake-Up flags */
		LL_PWR_ClearFlag_WU();

		LL_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);

	} else if (info.state == PM_STATE_SUSPEND_TO_IDLE) {

		lpm_hsem_lock();

		/* ensure HSI is the wake-up system clock */
		LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI);

		switch (info.substate_id) {
		case 1:
			/* enter STOP0 mode */
			LL_PWR_SetPowerMode(LL_PWR_MODE_STOP0);
			break;
		case 2:
			/* enter STOP1 mode */
			LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1);
			break;
		case 3:
			/* enter STOP2 mode */
			LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2);
			break;
		default:
			/* Release RCC semaphore */
			z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
			LOG_DBG("Unsupported power substate-id %u", info.substate_id);
			return;
		}

	} else {
		LOG_DBG("Unsupported power state %u", info.state);
		return;
	}

	/* Release RCC semaphore */
	z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);

	LL_LPM_EnableDeepSleep();

	/* enter SLEEP mode : WFE or WFI */
	k_cpu_idle();
}

/* Handle SOC specific activity after Low Power Mode Exit */
__weak void pm_power_state_exit_post_ops(struct pm_state_info info)
{
	/* Implementation of STM32 AN5289 algorithm to enter/exit lowpower */
	/* Release ENTRY_STOP_MODE semaphore */
	LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);
	z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_WAIT_FOREVER);

	if (info.state != PM_STATE_SUSPEND_TO_IDLE) {
		LOG_DBG("Unsupported power state %u", info.state);
	} else {
		switch (info.substate_id) {
		case 1:	/* STOP0 */
			__fallthrough;
		case 2:	/* STOP1 */
			__fallthrough;
		case 3:	/* STOP2 */
			LL_LPM_DisableSleepOnExit();
			LL_LPM_EnableSleep();
			break;
		default:
			LOG_DBG("Unsupported power substate-id %u",
				info.substate_id);
			break;
		}
		/* need to restore the clock */
		stm32_clock_control_init(NULL);
	}

	/* Release RCC semaphore */
	z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);

	/*
	 * System is now in active mode.
	 * Reenable interrupts which were disabled
	 * when OS started idling code.
	 */
	irq_unlock(0);
}

/* Initialize STM32 Power */
static int stm32_power_init(const struct device *dev)
{
	ARG_UNUSED(dev);

#ifdef CONFIG_DEBUG
	/* Enable the Debug Module during STOP mode */
	LL_DBGMCU_EnableDBGStopMode();
#endif /* CONFIG_DEBUG */

	return 0;
}

SYS_INIT(stm32_power_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
