#include <config.h>
#include "stdint.h"
#include <arch/machine.h>
#include <mode/machine/timer.h>
#include <plat/machine.h>
#include <arch/linker.h>
#include <plat/machine/devices.h>
#include <plat/machine/hardware.h>
#define GCNTWSTAT_CNTH (1U << 1)
#define GCNTWSTAT_CNTL (1U << 0)
#define GTCON_EN (1U << 8)
#define GTCON_COMP3_AUTOINC (1U << 7)
#define GTCON_COMP3_EN (1U << 6)
#define GTCON_COMP2_AUTOINC (1U << 5)
#define GTCON_COMP2_EN (1U << 4)
#define GTCON_COMP1_AUTOINC (1U << 3)
#define GTCON_COMP1_EN (1U << 2)
#define GTCON_COMP0_AUTOINC (1U << 1)
#define GTCON_COMP0_EN (1U << 0)
#define GINT_COMP3_IRQ (1U << 3)
#define GINT_COMP2_IRQ (1U << 2)
#define GINT_COMP1_IRQ (1U << 1)
#define GINT_COMP0_IRQ (1U << 0)
#define GWSTAT_TCON (1U << 16)
#define GWSTAT_COMP3_ADD_INC (1U << 14)
#define GWSTAT_COMP3H (1U << 13)
#define GWSTAT_COMP3L (1U << 12)
#define GWSTAT_COMP2_ADD_INC (1U << 10)
#define GWSTAT_COMP2H (1U << 9)
#define GWSTAT_COMP2L (1U << 8)
#define GWSTAT_COMP1_ADD_INC (1U << 6)
#define GWSTAT_COMP1H (1U << 5)
#define GWSTAT_COMP1L (1U << 4)
#define GWSTAT_COMP0_ADD_INC (1U << 2)
#define GWSTAT_COMP0H (1U << 1)
#define GWSTAT_COMP0L (1U << 0)
#define LTCON_XXX0 (1U << 3)
#define LTCON_INTERVAL_MODE (1U << 2)
#define LTCON_IEN (1U << 1)
#define LTCON_EN (1U << 0)
#define LTWSTAT_TCON (1U << 3)
#define LTWSTAT_TCOMP (1U << 1)
#define LTWSTAT_TCNT (1U << 0)
struct mct_global_map {
uint32_t reserved0[64];
uint32_t cntl;
uint32_t cnth;
uint32_t reserved1[1];
uint32_t cnt_wstat;
uint32_t reserved2[60];
uint32_t comp0l;
uint32_t comp0h;
uint32_t comp0_add_inc;
uint32_t comp0_res;
uint32_t comp1l;
uint32_t comp1h;
uint32_t comp1_add_inc;
uint32_t comp1_res;
uint32_t comp2l;
uint32_t comp2h;
uint32_t comp2_add_inc;
uint32_t comp2_res;
uint32_t comp3l;
uint32_t comp3h;
uint32_t comp3_add_inc;
uint32_t comp3_res;
uint32_t tcon;
uint32_t int_stat;
uint32_t int_en;
uint32_t wstat;
uint32_t reserved3[44];
};
struct mct_local_map {
uint32_t tcompl;
uint32_t tcntl;
uint32_t tcomph;
uint32_t tcnth;
uint32_t reserved0[4];
uint32_t tcon;
uint32_t int_stat;
uint32_t int_en;
uint32_t reserved1[2];
uint32_t wstat;
uint32_t reserved2[50];
};
struct mct_map {
struct mct_global_map global;
struct mct_local_map local[4];
};
static volatile struct mct_map* mct = (volatile struct mct_map*) EXYNOS_MCT_PPTR;
void
resetTimer(void)
{
if (config_set(CONFIG_ARM_CORTEX_A15)) {
resetGenericTimer();
} else {
mct->global.int_stat = GINT_COMP0_IRQ;
}
}
compile_assert(mct_reload_32_bit, TIMER_RELOAD <= 0xffffffff);
BOOT_CODE void
initTimer(void)
{
mct->global.wstat = mct->global.wstat;
mct->global.cnt_wstat = mct->global.cnt_wstat;
if (config_set(CONFIG_ARM_CORTEX_A15)) {
mct->global.tcon = GTCON_EN;
while (mct->global.wstat != GWSTAT_TCON);
mct->global.wstat = GWSTAT_TCON;
initGenericTimer();
} else {
mct->global.comp0_add_inc = TIMER_RELOAD;
uint64_t comparator_value = ((((uint64_t) mct->global.cnth) << 32llu)
| mct->global.cntl) + TIMER_RELOAD;
mct->global.comp0h = (uint32_t) (comparator_value >> 32u);
mct->global.comp0l = (uint32_t) comparator_value;
mct->global.int_en = GINT_COMP0_IRQ;
while (mct->global.wstat != (GWSTAT_COMP0H | GWSTAT_COMP0L | GWSTAT_COMP0_ADD_INC));
mct->global.wstat = (GWSTAT_COMP0H | GWSTAT_COMP0L | GWSTAT_COMP0_ADD_INC);
mct->global.tcon = GTCON_EN | GTCON_COMP0_EN | GTCON_COMP0_AUTOINC;
while (mct->global.wstat != GWSTAT_TCON);
mct->global.wstat = GWSTAT_TCON;
}
}