1/* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * This software may be distributed and modified according to the terms of 5 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 6 * See "LICENSE_GPLv2.txt" for details. 7 * 8 * @TAG(GD_GPL) 9 */ 10 11#include <config.h> 12#include <types.h> 13#include <machine/io.h> 14#include <kernel/vspace.h> 15#include <arch/machine.h> 16#include <arch/kernel/vspace.h> 17#include <plat/machine.h> 18#include <linker.h> 19#include <plat/machine/devices.h> 20#include <plat/machine/hardware.h> 21#include <plat/machine/timer.h> 22 23#define TIOCP_CFG_SOFTRESET BIT(0) 24 25#define TIER_MATCHENABLE BIT(0) 26#define TIER_OVERFLOWENABLE BIT(1) 27#define TIER_COMPAREENABLE BIT(2) 28 29#define TCLR_AUTORELOAD BIT(1) 30#define TCLR_COMPAREENABLE BIT(6) 31#define TCLR_STARTTIMER BIT(0) 32 33timer_t *timer = (timer_t *) DMTIMER0_PPTR; 34 35#define WDT_REG(base, off) ((volatile uint32_t *)((base) + (off))) 36#define WDT_REG_WWPS 0x34 37#define WDT_REG_WSPR 0x48 38#define WDT_WWPS_PEND_WSPR BIT(4) 39 40static BOOT_CODE void 41disableWatchdog(void) 42{ 43 uint32_t wdt = WDT1_PPTR; 44 45 // am335x ref man, sec 20.4.3.8 46 *WDT_REG(wdt, WDT_REG_WSPR) = 0xaaaa; 47 while ((*WDT_REG(wdt, WDT_REG_WWPS) & WDT_WWPS_PEND_WSPR)) { 48 continue; 49 } 50 *WDT_REG(wdt, WDT_REG_WSPR) = 0x5555; 51 while ((*WDT_REG(wdt, WDT_REG_WWPS) & WDT_WWPS_PEND_WSPR)) { 52 continue; 53 } 54} 55 56/* 57 * Enable DMTIMER clocks, otherwise their registers wont be accessible. 58 * This could be moved out of kernel. 59 */ 60static BOOT_CODE void 61enableTimers(void) 62{ 63 uint32_t cmper = CMPER_PPTR; 64 65 /* XXX repeat this for DMTIMER4..7 */ 66 /* select clock */ 67 *CMPER_REG(cmper, CMPER_CLKSEL_TIMER3) = CMPER_CKLSEL_MOSC; 68 while ((*CMPER_REG(cmper, CMPER_CLKSEL_TIMER3) & 3) != CMPER_CKLSEL_MOSC) { 69 continue; 70 } 71 72 /* enable clock */ 73 *CMPER_REG(cmper, CMPER_TIMER3_CLKCTRL) = CMPER_CLKCTRL_ENABLE; 74 while ((*CMPER_REG(cmper, CMPER_TIMER3_CLKCTRL) & 3) != CMPER_CLKCTRL_ENABLE) { 75 continue; 76 } 77} 78 79/* Configure dmtimer0 as kernel preemption timer */ 80BOOT_CODE void 81initTimer(void) 82{ 83 int timeout; 84 85 disableWatchdog(); 86 enableTimers(); 87 88 timer->cfg = TIOCP_CFG_SOFTRESET; 89 90 for (timeout = 10000; (timer->cfg & TIOCP_CFG_SOFTRESET) && timeout > 0; timeout--) 91 ; 92 if (!timeout) { 93 printf("init timer failed\n"); 94 return; 95 } 96 97 maskInterrupt(/*disable*/ true, DMTIMER0_IRQ); 98 fail("not implemented"); 99 100 /* Enables interrupt on overflow */ 101 timer->tier = TIER_OVERFLOWENABLE; 102 103 /* Set autoreload and start the timer */ 104 timer->tclr = TCLR_AUTORELOAD | TCLR_STARTTIMER; 105} 106 107BOOT_CODE void 108initIRQController(void) 109{ 110 intc->intcps_sysconfig = INTCPS_SYSCONFIG_SOFTRESET; 111 while (!(intc->intcps_sysstatus & INTCPS_SYSSTATUS_RESETDONE)) ; 112} 113 114BOOT_CODE void cpu_initLocalIRQController(void) {} 115 116void plat_cleanL2Range(paddr_t start, paddr_t end) {} 117void plat_invalidateL2Range(paddr_t start, paddr_t end) {} 118void plat_cleanInvalidateL2Range(paddr_t start, paddr_t end) {} 119void plat_cleanInvalidateCache(void) {} 120