/*
 * Copyright (c) 2016, 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 "qm_aon_counters.h"

static void (*callback)(void *) = NULL;
static void *callback_data;

static void pt_reset(const qm_scss_aon_t aonc)
{
	static bool first_run = true;
	uint32_t aonc_cfg;

	/* After POR, it is required to wait for one RTC clock cycle before
	 * asserting QM_AONPT_CTRL_RST.  Note the AON counter is enabled with an
	 * initial value of 0 at POR.
	 */
	if (first_run) {
		first_run = false;

		/* Ensure the AON counter is enabled */
		aonc_cfg = QM_SCSS_AON[aonc].aonc_cfg;
		QM_SCSS_AON[aonc].aonc_cfg = BIT(0);

		while (0 == QM_SCSS_AON[aonc].aonc_cnt) {
		}

		QM_SCSS_AON[aonc].aonc_cfg = aonc_cfg;
	}

	QM_SCSS_AON[aonc].aonpt_ctrl |= BIT(1);
}

QM_ISR_DECLARE(qm_aonpt_isr_0)
{
	if (callback) {
		(*callback)(callback_data);
	}

	QM_SCSS_AON[0].aonpt_ctrl |= BIT(0); /* Clear pending interrupts */
	QM_ISR_EOI(QM_IRQ_AONPT_0_VECTOR);
}

int qm_aonc_enable(const qm_scss_aon_t aonc)
{
	QM_CHECK(aonc < QM_SCSS_AON_NUM, -EINVAL);

	QM_SCSS_AON[aonc].aonc_cfg = 0x1;

	return 0;
}

int qm_aonc_disable(const qm_scss_aon_t aonc)
{
	QM_CHECK(aonc < QM_SCSS_AON_NUM, -EINVAL);

	QM_SCSS_AON[aonc].aonc_cfg = 0x0;

	return 0;
}

int qm_aonc_get_value(const qm_scss_aon_t aonc, uint32_t * const val)
{
	QM_CHECK(aonc < QM_SCSS_AON_NUM, -EINVAL);
	QM_CHECK(val != NULL, -EINVAL);

	*val = QM_SCSS_AON[aonc].aonc_cnt;
	return 0;
}

int qm_aonpt_set_config(const qm_scss_aon_t aonc,
			const qm_aonpt_config_t *const cfg)
{
	QM_CHECK(aonc < QM_SCSS_AON_NUM, -EINVAL);
	QM_CHECK(cfg != NULL, -EINVAL);

	QM_SCSS_AON[aonc].aonpt_ctrl |= BIT(0); /* Clear pending interrupts */
	QM_SCSS_AON[aonc].aonpt_cfg = cfg->count;
	if (cfg->int_en) {
		callback = cfg->callback;
		callback_data = cfg->callback_data;
	} else {
		callback = NULL;
	}
	pt_reset(aonc);

	return 0;
}

int qm_aonpt_get_value(const qm_scss_aon_t aonc, uint32_t *const val)
{
	QM_CHECK(aonc < QM_SCSS_AON_NUM, -EINVAL);
	QM_CHECK(val != NULL, -EINVAL);

	*val = QM_SCSS_AON[aonc].aonpt_cnt;
	return 0;
}

int qm_aonpt_get_status(const qm_scss_aon_t aonc, bool *const status)
{
	QM_CHECK(aonc < QM_SCSS_AON_NUM, -EINVAL);
	QM_CHECK(status != NULL, -EINVAL);

	*status = QM_SCSS_AON[aonc].aonpt_stat & BIT(0);
	return 0;
}

int qm_aonpt_clear(const qm_scss_aon_t aonc)
{
	QM_CHECK(aonc < QM_SCSS_AON_NUM, -EINVAL);

	QM_SCSS_AON[aonc].aonpt_ctrl |= BIT(0);

	return 0;
}

int qm_aonpt_reset(const qm_scss_aon_t aonc)
{
	QM_CHECK(aonc < QM_SCSS_AON_NUM, -EINVAL);

	pt_reset(aonc);

	return 0;
}
