#include <config.h>
#include <types.h>
#include <machine/io.h>
#include <kernel/vspace.h>
#include <arch/machine.h>
#include <arch/kernel/vspace.h>
#include <plat/machine.h>
#include <arch/linker.h>
#include <plat/machine/devices.h>
#include <plat/machine/hardware.h>
#define TIMER_INTERVAL_MS (CONFIG_TIMER_TICK_MS)
#define TIOCP_CFG_SOFTRESET BIT(0)
#define TIER_MATCHENABLE BIT(0)
#define TIER_OVERFLOWENABLE BIT(1)
#define TIER_COMPAREENABLE BIT(2)
#define TCLR_AUTORELOAD BIT(1)
#define TCLR_COMPAREENABLE BIT(6)
#define TCLR_STARTTIMER BIT(0)
#define TISR_OVF_FLAG (BIT(0) | BIT(1) | BIT(2))
#define TICKS_PER_SECOND 32768
#define TIMER_INTERVAL_TICKS ((int)(1UL * TIMER_INTERVAL_MS * TICKS_PER_SECOND / 1000))
volatile struct TIMER_map {
uint32_t tidr; uint32_t padding1[3];
uint32_t cfg; uint32_t padding2[3];
uint32_t tieoi; uint32_t tisrr; uint32_t tisr; uint32_t tier; uint32_t ticr; uint32_t twer; uint32_t tclr; uint32_t tcrr; uint32_t tldr; uint32_t ttgr; uint32_t twps; uint32_t tmar; uint32_t tcar1; uint32_t tsicr; uint32_t tcar2; } *timer = (volatile void*)DMTIMER0_PPTR;
void
resetTimer(void)
{
timer->tisr = TISR_OVF_FLAG;
ackInterrupt(DMTIMER0_IRQ);
}
#define WDT_REG(base, off) ((volatile uint32_t *)((base) + (off)))
#define WDT_REG_WWPS 0x34
#define WDT_REG_WSPR 0x48
#define WDT_WWPS_PEND_WSPR BIT(4)
static BOOT_CODE void
disableWatchdog(void)
{
uint32_t wdt = WDT1_PPTR;
*WDT_REG(wdt, WDT_REG_WSPR) = 0xaaaa;
while ((*WDT_REG(wdt, WDT_REG_WWPS) & WDT_WWPS_PEND_WSPR)) {
continue;
}
*WDT_REG(wdt, WDT_REG_WSPR) = 0x5555;
while ((*WDT_REG(wdt, WDT_REG_WWPS) & WDT_WWPS_PEND_WSPR)) {
continue;
}
}
static BOOT_CODE void
enableTimers(void)
{
uint32_t cmper = CMPER_PPTR;
*CMPER_REG(cmper, CMPER_CLKSEL_TIMER3) = CMPER_CKLSEL_MOSC;
while ((*CMPER_REG(cmper, CMPER_CLKSEL_TIMER3) & 3) != CMPER_CKLSEL_MOSC) {
continue;
}
*CMPER_REG(cmper, CMPER_TIMER3_CLKCTRL) = CMPER_CLKCTRL_ENABLE;
while ((*CMPER_REG(cmper, CMPER_TIMER3_CLKCTRL) & 3) != CMPER_CLKCTRL_ENABLE) {
continue;
}
}
BOOT_CODE void
initTimer(void)
{
int timeout;
disableWatchdog();
enableTimers();
timer->cfg = TIOCP_CFG_SOFTRESET;
for (timeout = 10000; (timer->cfg & TIOCP_CFG_SOFTRESET) && timeout > 0; timeout--)
;
if (!timeout) {
printf("init timer failed\n");
return;
}
maskInterrupt( true, DMTIMER0_IRQ);
timer->tldr = 0xFFFFFFFFUL - TIMER_INTERVAL_TICKS;
timer->tier = TIER_OVERFLOWENABLE;
timer->tcrr = 0xFFFFFFFFUL - TIMER_INTERVAL_TICKS;
timer->tclr = TCLR_AUTORELOAD | TCLR_STARTTIMER;
}
BOOT_CODE void
initIRQController(void)
{
intc->intcps_sysconfig = INTCPS_SYSCONFIG_SOFTRESET;
while (!(intc->intcps_sysstatus & INTCPS_SYSSTATUS_RESETDONE)) ;
}
BOOT_CODE void cpu_initLocalIRQController(void) {}
void plat_cleanL2Range(paddr_t start, paddr_t end) {}
void plat_invalidateL2Range(paddr_t start, paddr_t end) {}
void plat_cleanInvalidateL2Range(paddr_t start, paddr_t end) {}
void plat_cleanInvalidateCache(void) {}