/* * 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; }