/*
 * Copyright (c) 2017, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "power_states.h"
#include "clk.h"
#include "qm_comparator.h"
#include "qm_isr.h"
#include "qm_adc.h"
#include "qm_flash.h"
#include "soc_watch.h"

typedef struct {
	uint32_t ac_power_save;
	uint32_t clk_gate_save;
	uint32_t sys_clk_ctl_save;
	uint32_t osc0_cfg_save;
	uint32_t osc1_cfg_save;
	uint32_t adc_mode_save;
	uint32_t aon_vr_save;
	uint32_t flash_tmg_save;
	uint32_t ext_clock_save;
	uint32_t lp_clk_save;
	uint32_t pmux_slew_save;
} power_context_t;

static power_context_t power_context;

void qm_power_cpu_halt(void)
{
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_HALT, 0);
	/*
	 * STI sets the IF flag. After the IF flag is set,
	 * the core begins responding to external,
	 * maskable interrupts after the next instruction is executed.
	 * When this function is called with interrupts disabled,
	 * this guarantees that an interrupt is caught only
	 * after the processor has transitioned into HLT.
	 */
	__asm__ __volatile__("sti\n\t"
			     "hlt\n\t");
}

static void clear_all_pending_interrupts(void)
{
	/* Clear comparator interrupts. */
	QM_SCSS_CMP->cmp_stat_clr = -1;

	/* Clear RTC interrupts. */
	QM_RTC[QM_RTC_0]->rtc_eoi;

	/* Clear timers interrupt flag. */
	QM_PWM[QM_PWM_0]->timerseoi;

	/* Clear GPIO interrupts. */
	QM_GPIO[QM_GPIO_0]->gpio_porta_eoi = -1;
}

void qm_power_soc_sleep(void)
{
	/* Save register values. */
	power_context.ac_power_save = QM_SCSS_CMP->cmp_pwr;
	power_context.clk_gate_save = QM_SCSS_CCU->ccu_periph_clk_gate_ctl;
	power_context.sys_clk_ctl_save = QM_SCSS_CCU->ccu_sys_clk_ctl;
	power_context.osc0_cfg_save = QM_SCSS_CCU->osc0_cfg1;
	power_context.adc_mode_save = QM_ADC->adc_op_mode;
	power_context.flash_tmg_save = QM_FLASH[QM_FLASH_0]->tmg_ctrl;
	power_context.lp_clk_save = QM_SCSS_CCU->ccu_lp_clk_ctl;

	QM_SCSS_GP->gps0 |= QM_GPS0_POWER_STATE_SLEEP;

	/* Clear any pending interrupts. */
	clear_all_pending_interrupts();

	qm_adc_set_mode(QM_ADC_0, QM_ADC_MODE_PWR_DOWN);

	/* Turn off high power comparators. */
	QM_SCSS_CMP->cmp_pwr &= QM_AC_HP_COMPARATORS_MASK;

	/*
	 * Program WAKE_MASK.WAKE_MASK[31:0],
	 * CCU_LP_CLK_CTL.WAKE_PROBE_MODE_MASK registers identical to Interrupt
	 * Mask registers.
	 */
	QM_SCSS_CCU->ccu_lp_clk_ctl &= ~QM_WAKE_PROBE_MODE_MASK;
	/* Enable all wake sources as interrupts. */
	QM_SCSS_CCU->wake_mask = 0;

	/*
	 * Ensure that powering down of oscillators is delayed by hardware until
	 * core  executes HALT instruction.
	 */
	/* HYB_OSC_PD_LATCH_EN = 0, RTC_OSC_PD_LATCH_EN=0 */
	QM_SCSS_CCU->ccu_lp_clk_ctl &=
	    ~(QM_HYB_OSC_PD_LATCH_EN | QM_RTC_OSC_PD_LATCH_EN);

	/* Ensure that at exit, hardware will switch system clock to Hybrid
	 * oscillator clock so as to minimize exit latency by running at higher
	 * frequency than RTC clock.
	 */
	/* CCU_LP_CLK_CTL.CCU_EXIT_TO_HYBOSC */
	QM_SCSS_CCU->ccu_lp_clk_ctl |=
	    QM_CCU_EXIT_TO_HYBOSC | QM_CCU_MEM_HALT_EN | QM_CCU_CPU_HALT_EN;
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_CCU_LP_CLK_CTL);

	/*
	 * Only the following peripherals can be used as a wakeup source:
	 *  - GPIO Interrupts
	 *  - AON timers
	 *  - RTC
	 *  - low power comparators
	 */
	clk_periph_disable(
	    CLK_PERIPH_I2C_M0 | CLK_PERIPH_SPI_S | CLK_PERIPH_SPI_M0 |
	    CLK_PERIPH_GPIO_DB | CLK_PERIPH_WDT_REGISTER |
	    CLK_PERIPH_PWM_REGISTER | CLK_PERIPH_GPIO_REGISTER |
	    CLK_PERIPH_SPI_M0_REGISTER | CLK_PERIPH_SPI_S_REGISTER |
	    CLK_PERIPH_UARTA_REGISTER | CLK_PERIPH_UARTB_REGISTER |
	    CLK_PERIPH_I2C_M0_REGISTER);

	/* Set system clock source to hyb osc, 4 MHz, scaled to 512 kHz. */
	clk_sys_set_mode(CLK_SYS_HYB_OSC_4MHZ, CLK_SYS_DIV_8);

	/* Set the RAR to retention mode. */
	qm_rar_set_mode(QM_RAR_RETENTION);

	/*
	 * If wake source is any of AON Timer, RTC, GPIO interrupt, program
	 * CCU_SYS_CLK_CTL.CCU_SYS_CLK_SEL to RTC Oscillator.
	 */
	/* Enter SoC sleep mode. */
	qm_power_cpu_halt();
}

void qm_power_soc_sleep_restore(void)
{
	/* From here on, restore the SoC to an active state. */
	/* Set the RAR to normal mode. */
	qm_rar_set_mode(QM_RAR_NORMAL);

	/*
	 * Since we are running below 4MHz, 0 wait states are configured.
	 * If the previous frequency was > 4MHz, 0 wait states will
	 * violate the flash timings.
	 * In the worst case scenario, when switching back to 32MHz,
	 * 2 wait states will be restored.
	 * This setting will be too conservative until the frequency has been
	 * restored.
	 */
	QM_FLASH[QM_FLASH_0]->tmg_ctrl = power_context.flash_tmg_save;

	/* Restore all previous values. */
	QM_SCSS_CCU->ccu_sys_clk_ctl = power_context.sys_clk_ctl_save;
	/* Re-apply clock divider values. DIV_EN must go 0 -> 1. */
	QM_SCSS_CCU->ccu_sys_clk_ctl &=
	    ~(QM_CCU_SYS_CLK_DIV_EN | QM_CCU_RTC_CLK_DIV_EN);
	QM_SCSS_CCU->ccu_sys_clk_ctl |=
	    QM_CCU_SYS_CLK_DIV_EN | QM_CCU_RTC_CLK_DIV_EN;

	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_CCU_SYS_CLK_CTL);

	/* Wait for the XTAL or SI oscillator to stabilise. */
	while (!(QM_SCSS_CCU->osc0_stat1 &
		 (QM_OSC0_LOCK_SI | QM_OSC0_LOCK_XTAL))) {
	};

	/* Restore original clocking, ADC, analog comparator states. */
	QM_SCSS_CCU->osc0_cfg1 = power_context.osc0_cfg_save;
	QM_SCSS_CCU->ccu_periph_clk_gate_ctl = power_context.clk_gate_save;
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_OSC0_CFG1);
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER,
			    SOCW_REG_CCU_PERIPH_CLK_GATE_CTL);
	QM_SCSS_CMP->cmp_pwr = power_context.ac_power_save;
	QM_ADC->adc_op_mode = power_context.adc_mode_save;
	QM_SCSS_CCU->ccu_lp_clk_ctl = power_context.lp_clk_save;

	QM_SCSS_GP->gps0 &= ~QM_GPS0_POWER_STATE_SLEEP;
}

void qm_power_soc_deep_sleep(const qm_power_wake_event_t wake_event)
{
	/* Save register values. */
	power_context.ac_power_save = QM_SCSS_CMP->cmp_pwr;
	power_context.clk_gate_save = QM_SCSS_CCU->ccu_periph_clk_gate_ctl;
	power_context.sys_clk_ctl_save = QM_SCSS_CCU->ccu_sys_clk_ctl;
	power_context.osc0_cfg_save = QM_SCSS_CCU->osc0_cfg1;
	power_context.osc1_cfg_save = QM_SCSS_CCU->osc1_cfg0;
	power_context.adc_mode_save = QM_ADC->adc_op_mode;
	power_context.aon_vr_save = QM_SCSS_PMU->aon_vr;
	power_context.flash_tmg_save = QM_FLASH[QM_FLASH_0]->tmg_ctrl;
	power_context.pmux_slew_save = QM_SCSS_PMUX->pmux_slew[0];
	power_context.ext_clock_save = QM_SCSS_CCU->ccu_ext_clock_ctl;
	power_context.lp_clk_save = QM_SCSS_CCU->ccu_lp_clk_ctl;

	QM_SCSS_GP->gps0 |= QM_GPS0_POWER_STATE_DEEP_SLEEP;

	/* Clear any pending interrupts. */
	clear_all_pending_interrupts();

	/*
	 * Clear the wake mask bits. Default behaviour is to wake from GPIO /
	 * comparator.
	 */
	switch (wake_event) {
	case QM_POWER_WAKE_FROM_RTC:
		QM_SCSS_CCU->wake_mask =
		    SET_ALL_BITS & ~QM_CCU_WAKE_MASK_RTC_BIT;
		break;
	case QM_POWER_WAKE_FROM_GPIO_COMP:
	default:
		QM_SCSS_CCU->wake_mask = SET_ALL_BITS &
					 ~(QM_CCU_WAKE_MASK_COMPARATOR_BIT |
					   QM_CCU_WAKE_MASK_GPIO_BIT);
		break;
	}

	qm_adc_set_mode(QM_ADC_0, QM_ADC_MODE_DEEP_PWR_DOWN);

	/* Turn off high power comparators. */
	QM_SCSS_CMP->cmp_pwr &= QM_AC_HP_COMPARATORS_MASK;

	/* Disable all peripheral clocks. */
	clk_periph_disable(CLK_PERIPH_REGISTER);

	/* Disable external clocks. */
	QM_SCSS_CCU->ccu_ext_clock_ctl = 0;
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_CCU_EXT_CLK_CTL);

	/* Set slew rate of all pins to 12mA. */
	QM_SCSS_PMUX->pmux_slew[0] = 0;
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_PMUX_SLEW);

	if (wake_event != QM_POWER_WAKE_FROM_RTC) {
		/* Disable RTC. */
		QM_SCSS_CCU->osc1_cfg0 &= ~QM_OSC1_PD;

		/* Set system clock source to
		 * Silicon Oscillator 4 MHz, scaled down to 32 kHz. */
		clk_sys_set_mode(CLK_SYS_HYB_OSC_4MHZ, CLK_SYS_DIV_128);
	}

	/* Power down the oscillator after the halt instruction is executed. */
	QM_SCSS_CCU->ccu_lp_clk_ctl &= ~QM_HYB_OSC_PD_LATCH_EN;
	/*
	 * Enable memory halt and CPU halt. When exiting sleep mode, use hybrid
	 * oscillator.
	 */
	QM_SCSS_CCU->ccu_lp_clk_ctl |=
	    QM_CCU_EXIT_TO_HYBOSC | QM_CCU_MEM_HALT_EN | QM_CCU_CPU_HALT_EN;
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_CCU_LP_CLK_CTL);

	/* Power down hybrid oscillator. */
	QM_SCSS_CCU->osc0_cfg1 |= QM_OSC0_PD;

	/* Disable gpio debounce clocking. */
	QM_SCSS_CCU->ccu_gpio_db_clk_ctl &= ~QM_CCU_GPIO_DB_CLK_EN;
	/* Set retention voltage to 1.35V. */
	/* SCSS.OSC0_CFG0.OSC0_HYB_SET_REG1.OSC0_CFG0[0]  = 1; */
	QM_SCSS_CCU->osc0_cfg0 |= QM_SI_OSC_1V2_MODE;

	/* Enable low voltage mode for flash controller. */
	/* FlashCtrl.CTRL.LVE_MODE = 1; */
	QM_FLASH[QM_FLASH_0]->ctrl |= QM_FLASH_LVE_MODE;

	/* Select 1.35V for voltage regulator. */
	/* SCSS.AON_VR.VSEL = 0xB; */
	QM_SCSS_PMU->aon_vr =
	    (QM_AON_VR_PASS_CODE |
	     (power_context.aon_vr_save & QM_AON_VR_VSEL_MASK) |
	     QM_AON_VR_VSEL_1V35);
	/* SCSS.AON_VR.ROK_BUF_VREG_MASK = 1; */
	QM_SCSS_PMU->aon_vr = (QM_AON_VR_PASS_CODE | QM_SCSS_PMU->aon_vr |
			       QM_AON_VR_ROK_BUF_VREG_MASK);

	/* SCSS.AON_VR.VSEL_STROBE = 1;  */
	QM_SCSS_PMU->aon_vr =
	    (QM_AON_VR_PASS_CODE | QM_SCSS_PMU->aon_vr | QM_AON_VR_VSTRB);

	/* Wait >= 1 usec, at 256 kHz this is 1 cycle. */
	__asm__ __volatile__("nop");

	/* SCSS.AON_VR.VSEL_STROBE = 0; */
	QM_SCSS_PMU->aon_vr =
	    (QM_AON_VR_PASS_CODE | (QM_SCSS_PMU->aon_vr & ~QM_AON_VR_VSTRB));

	/* Wait >= 2 usec, at 256 kHz this is 1 cycle. */
	__asm__ __volatile__("nop");

	/* Set the RAR to retention mode. */
	qm_rar_set_mode(QM_RAR_RETENTION);

	if (wake_event == QM_POWER_WAKE_FROM_RTC) {
		/* Start running on the rtc clock */
		clk_sys_set_mode(CLK_SYS_RTC_OSC, CLK_SYS_DIV_1);
	}

	/* Disable all peripheral clocks. */
	clk_periph_disable(CLK_PERIPH_REGISTER | CLK_PERIPH_CLK);

	/* Enter SoC deep sleep mode. */
	qm_power_cpu_halt();
}

void qm_power_soc_deep_sleep_restore(void)
{
	/* We are now exiting from deep sleep mode. */
	/* Set the RAR to normal mode. */
	qm_rar_set_mode(QM_RAR_NORMAL);

	/*
	 * Since we are running below 4MHz, 0 wait states are configured.
	 * If the previous frequency was > 4MHz, 0 wait states will
	 * violate the flash timings.
	 * In the worst case scenario, when switching back to 32MHz,
	 * 2 wait states will be restored.
	 * This setting will be too conservative until the frequency has been
	 * restored.
	 */
	QM_FLASH[QM_FLASH_0]->tmg_ctrl = power_context.flash_tmg_save;

	/* Restore operating voltage to 1.8V. */
	/* SCSS.AON_VR.VSEL = 0x10; */
	QM_SCSS_PMU->aon_vr =
	    (QM_AON_VR_PASS_CODE | (QM_SCSS_PMU->aon_vr & QM_AON_VR_VSEL_MASK) |
	     QM_AON_VR_VSEL_1V8 | QM_AON_VR_ROK_BUF_VREG_MASK);

	/* SCSS.AON_VR.VSEL_STROBE = 1;  */
	QM_SCSS_PMU->aon_vr =
	    (QM_AON_VR_PASS_CODE | QM_SCSS_PMU->aon_vr | QM_AON_VR_VSTRB);

	/* Wait >= 1 usec, at 256 kHz this is 1 cycle. */
	__asm__ __volatile__("nop");

	/* SCSS.AON_VR.VSEL_STROBE = 0; */
	QM_SCSS_PMU->aon_vr =
	    (QM_AON_VR_PASS_CODE | (QM_SCSS_PMU->aon_vr & ~QM_AON_VR_VSTRB));

	/* Wait >= 2 usec, at 256 kHz this is 1 cycle. */
	__asm__ __volatile__("nop");

	/* SCSS.AON_VR.ROK_BUF_VREG_MASK = 0;  */
	QM_SCSS_PMU->aon_vr =
	    (QM_AON_VR_PASS_CODE |
	     (QM_SCSS_PMU->aon_vr & ~QM_AON_VR_ROK_BUF_VREG_MASK));

	/* Wait >= 1 usec, at 256 kHz this is 1 cycle. */
	__asm__ __volatile__("nop");

	/* Wait for voltage regulator to attain 1.8V regulation. */
	while (!(QM_SCSS_PMU->aon_vr & QM_AON_VR_ROK_BUF_VREG_STATUS)) {
	}

	/* SCSS.OSC0_CFG0.OSC0_HYB_SET_REG1.OSC0_CFG0[0]  = 0; */
	QM_SCSS_CCU->osc0_cfg0 &= ~QM_SI_OSC_1V2_MODE;

	/* FlashCtrl.CTRL.LVE_MODE = 0; */
	QM_FLASH[QM_FLASH_0]->ctrl &= ~QM_FLASH_LVE_MODE;

	/* Restore all previous values. */
	QM_SCSS_CCU->ccu_sys_clk_ctl = power_context.sys_clk_ctl_save;
	/* Re-apply clock divider values. DIV_EN must go 0 -> 1. */
	QM_SCSS_CCU->ccu_sys_clk_ctl &=
	    ~(QM_CCU_SYS_CLK_DIV_EN | QM_CCU_RTC_CLK_DIV_EN);
	QM_SCSS_CCU->ccu_sys_clk_ctl |=
	    QM_CCU_SYS_CLK_DIV_EN | QM_CCU_RTC_CLK_DIV_EN;

	/* Wait for the XTAL or SI oscillator to stabilise. */
	while (!(QM_SCSS_CCU->osc0_stat1 &
		 (QM_OSC0_LOCK_SI | QM_OSC0_LOCK_XTAL))) {
	};
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_CCU_SYS_CLK_CTL);

	/* Re-enable clocks. */
	clk_periph_enable(CLK_PERIPH_REGISTER);

	/* Re-enable gpio debounce clocking. */
	QM_SCSS_CCU->ccu_gpio_db_clk_ctl |= QM_CCU_GPIO_DB_CLK_EN;

	/* Restore original clocking, ADC, analog comparator states. */
	QM_SCSS_CCU->osc0_cfg1 = power_context.osc0_cfg_save;
	QM_SCSS_CCU->ccu_periph_clk_gate_ctl = power_context.clk_gate_save;
	QM_SCSS_CCU->osc1_cfg0 = power_context.osc1_cfg_save;

	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_OSC0_CFG1);
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER,
			    SOCW_REG_CCU_PERIPH_CLK_GATE_CTL);
	QM_SCSS_CMP->cmp_pwr = power_context.ac_power_save;
	QM_ADC->adc_op_mode = power_context.adc_mode_save;

	QM_SCSS_PMUX->pmux_slew[0] = power_context.pmux_slew_save;
	QM_SCSS_CCU->ccu_ext_clock_ctl = power_context.ext_clock_save;
	QM_SCSS_CCU->ccu_lp_clk_ctl = power_context.lp_clk_save;

	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_PMUX_SLEW);
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_CCU_LP_CLK_CTL);
	SOC_WATCH_LOG_EVENT(SOCW_EVENT_REGISTER, SOCW_REG_CCU_EXT_CLK_CTL);

	QM_SCSS_CCU->wake_mask = SET_ALL_BITS;
	QM_SCSS_GP->gps0 &= ~QM_GPS0_POWER_STATE_DEEP_SLEEP;
}

void qm_power_soc_restore(void)
{
	/*
	 * If the SoC is waking from sleep or deep sleep mode then the full
	 * system state must be restored.
	 */
	if (QM_SCSS_GP->gps0 & QM_GPS0_POWER_STATE_SLEEP) {
		qm_power_soc_sleep_restore();
	} else if (QM_SCSS_GP->gps0 & QM_GPS0_POWER_STATE_DEEP_SLEEP) {
		qm_power_soc_deep_sleep_restore();
	}
}

int qm_rar_set_mode(const qm_rar_state_t mode)
{
	QM_CHECK(mode <= QM_RAR_RETENTION, -EINVAL);
	volatile uint32_t i = 32;
	volatile uint32_t reg;

	switch (mode) {
	case QM_RAR_RETENTION:
		QM_SCSS_PMU->aon_vr |=
		    (QM_AON_VR_PASS_CODE | QM_AON_VR_ROK_BUF_VREG_MASK);
		QM_SCSS_PMU->aon_vr |=
		    (QM_AON_VR_PASS_CODE | QM_AON_VR_VREG_SEL);
		break;

	case QM_RAR_NORMAL:
		reg = QM_SCSS_PMU->aon_vr & ~QM_AON_VR_VREG_SEL;
		QM_SCSS_PMU->aon_vr = QM_AON_VR_PASS_CODE | reg;
		/* Wait for >= 2usec, at most 64 clock cycles. */
		while (i--) {
			__asm__ __volatile__("nop");
		}
		reg = QM_SCSS_PMU->aon_vr & ~QM_AON_VR_ROK_BUF_VREG_MASK;
		QM_SCSS_PMU->aon_vr = QM_AON_VR_PASS_CODE | reg;
		break;
	}
	return 0;
}
