1.1 --- a/board-nanonote.c Sat Jun 06 18:03:55 2015 +0200
1.2 +++ b/board-nanonote.c Sat Jun 06 23:29:51 2015 +0200
1.3 @@ -3,7 +3,8 @@
1.4 *
1.5 * Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
1.6 * Copyright (C) Xiangfu Liu <xiangfu.z@gmail.com>
1.7 - * Copyright (c) 2006 Ingenic Semiconductor, <jlwei@ingenic.cn>
1.8 + * Copyright (C) 2006 Ingenic Semiconductor, <jlwei@ingenic.cn>
1.9 + * Copyright (C) 2003 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
1.10 *
1.11 * This program is free software; you can redistribute it and/or modify it under
1.12 * the terms of the GNU General Public License as published by the Free Software
1.13 @@ -234,3 +235,232 @@
1.14
1.15 /* everything is ok now */
1.16 }
1.17 +
1.18 +void rtc_init(void)
1.19 +{
1.20 + while ( !__rtc_write_ready()) ;
1.21 + __rtc_enable_alarm(); /* enable alarm */
1.22 +
1.23 + while ( !__rtc_write_ready())
1.24 + ;
1.25 + REG_RTC_RGR = 0x00007fff; /* type value */
1.26 +
1.27 + while ( !__rtc_write_ready())
1.28 + ;
1.29 + REG_RTC_HWFCR = 0x0000ffe0; /* Power on delay 2s */
1.30 +
1.31 + while ( !__rtc_write_ready())
1.32 + ;
1.33 + REG_RTC_HRCR = 0x00000fe0; /* reset delay 125ms */
1.34 +}
1.35 +
1.36 +/*
1.37 + * Timer routines
1.38 + */
1.39 +
1.40 +#define TIMER_CHAN 0
1.41 +#define TIMER_FDATA 0xffff /* Timer full data value */
1.42 +#define TIMER_HZ CONFIG_SYS_HZ
1.43 +
1.44 +#define READ_TIMER REG_TCU_TCNT(TIMER_CHAN) /* macro to read the 16 bit timer */
1.45 +
1.46 +static unsigned long timestamp;
1.47 +static unsigned long lastdec;
1.48 +
1.49 +void reset_timer_masked(void);
1.50 +unsigned long get_timer_masked(void);
1.51 +void udelay_masked(unsigned long usec);
1.52 +
1.53 +/*
1.54 + * timer without interrupts
1.55 + */
1.56 +
1.57 +int timer_init(void)
1.58 +{
1.59 + REG_TCU_TCSR(TIMER_CHAN) = TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN;
1.60 + REG_TCU_TCNT(TIMER_CHAN) = 0;
1.61 + REG_TCU_TDHR(TIMER_CHAN) = 0;
1.62 + REG_TCU_TDFR(TIMER_CHAN) = TIMER_FDATA;
1.63 +
1.64 + REG_TCU_TMSR = (1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)); /* mask irqs */
1.65 + REG_TCU_TSCR = (1 << TIMER_CHAN); /* enable timer clock */
1.66 + REG_TCU_TESR = (1 << TIMER_CHAN); /* start counting up */
1.67 +
1.68 + lastdec = 0;
1.69 + timestamp = 0;
1.70 +
1.71 + return 0;
1.72 +}
1.73 +
1.74 +void reset_timer(void)
1.75 +{
1.76 + reset_timer_masked ();
1.77 +}
1.78 +
1.79 +unsigned long get_timer(unsigned long base)
1.80 +{
1.81 + return get_timer_masked () - base;
1.82 +}
1.83 +
1.84 +void set_timer(unsigned long t)
1.85 +{
1.86 + timestamp = t;
1.87 +}
1.88 +
1.89 +void udelay (unsigned long usec)
1.90 +{
1.91 + unsigned long tmo,tmp;
1.92 +
1.93 + /* normalize */
1.94 + if (usec >= 1000) {
1.95 + tmo = usec / 1000;
1.96 + tmo *= TIMER_HZ;
1.97 + tmo /= 1000;
1.98 + }
1.99 + else {
1.100 + if (usec >= 1) {
1.101 + tmo = usec * TIMER_HZ;
1.102 + tmo /= (1000*1000);
1.103 + }
1.104 + else
1.105 + tmo = 1;
1.106 + }
1.107 +
1.108 + /* check for rollover during this delay */
1.109 + tmp = get_timer (0);
1.110 + if ((tmp + tmo) < tmp )
1.111 + reset_timer_masked(); /* timer would roll over */
1.112 + else
1.113 + tmo += tmp;
1.114 +
1.115 + while (get_timer_masked () < tmo);
1.116 +}
1.117 +
1.118 +void reset_timer_masked (void)
1.119 +{
1.120 + /* reset time */
1.121 + lastdec = READ_TIMER;
1.122 + timestamp = 0;
1.123 +}
1.124 +
1.125 +unsigned long get_timer_masked (void)
1.126 +{
1.127 + unsigned long now = READ_TIMER;
1.128 +
1.129 + if (lastdec <= now) {
1.130 + /* normal mode */
1.131 + timestamp += (now - lastdec);
1.132 + } else {
1.133 + /* we have an overflow ... */
1.134 + timestamp += TIMER_FDATA + now - lastdec;
1.135 + }
1.136 + lastdec = now;
1.137 +
1.138 + return timestamp;
1.139 +}
1.140 +
1.141 +void udelay_masked (unsigned long usec)
1.142 +{
1.143 + unsigned long tmo;
1.144 + unsigned long endtime;
1.145 + signed long diff;
1.146 +
1.147 + /* normalize */
1.148 + if (usec >= 1000) {
1.149 + tmo = usec / 1000;
1.150 + tmo *= TIMER_HZ;
1.151 + tmo /= 1000;
1.152 + } else {
1.153 + if (usec > 1) {
1.154 + tmo = usec * TIMER_HZ;
1.155 + tmo /= (1000*1000);
1.156 + } else {
1.157 + tmo = 1;
1.158 + }
1.159 + }
1.160 +
1.161 + endtime = get_timer_masked () + tmo;
1.162 +
1.163 + do {
1.164 + unsigned long now = get_timer_masked ();
1.165 + diff = endtime - now;
1.166 + } while (diff >= 0);
1.167 +}
1.168 +
1.169 +/*
1.170 + * This function is derived from PowerPC code (read timebase as long long).
1.171 + * On MIPS it just returns the timer value.
1.172 + */
1.173 +unsigned long long get_ticks(void)
1.174 +{
1.175 + return get_timer(0);
1.176 +}
1.177 +
1.178 +/*
1.179 + * This function is derived from PowerPC code (timebase clock frequency).
1.180 + * On MIPS it returns the number of timer ticks per second.
1.181 + */
1.182 +unsigned long get_tbclk (void)
1.183 +{
1.184 + return TIMER_HZ;
1.185 +}
1.186 +
1.187 +/* CPU-specific routines from U-Boot.
1.188 + See: uboot-xburst/files/arch/mips/cpu/xburst/cpu.c
1.189 + See: u-boot/arch/mips/include/asm/cacheops.h
1.190 +*/
1.191 +
1.192 +#define Index_Store_Tag_I 0x08
1.193 +#define Index_Writeback_Inv_D 0x15
1.194 +
1.195 +void flush_icache_all(void)
1.196 +{
1.197 + u32 addr, t = 0;
1.198 +
1.199 + asm volatile ("mtc0 $0, $28"); /* Clear Taglo */
1.200 + asm volatile ("mtc0 $0, $29"); /* Clear TagHi */
1.201 +
1.202 + for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_ICACHE_SIZE;
1.203 + addr += CONFIG_SYS_CACHELINE_SIZE) {
1.204 + asm volatile (
1.205 + ".set mips3\n\t"
1.206 + " cache %0, 0(%1)\n\t"
1.207 + ".set mips2\n\t"
1.208 + :
1.209 + : "I" (Index_Store_Tag_I), "r"(addr));
1.210 + }
1.211 +
1.212 + /* invalicate btb */
1.213 + asm volatile (
1.214 + ".set mips32\n\t"
1.215 + "mfc0 %0, $16, 7\n\t"
1.216 + "nop\n\t"
1.217 + "ori %0,2\n\t"
1.218 + "mtc0 %0, $16, 7\n\t"
1.219 + ".set mips2\n\t"
1.220 + :
1.221 + : "r" (t));
1.222 +}
1.223 +
1.224 +void flush_dcache_all(void)
1.225 +{
1.226 + u32 addr;
1.227 +
1.228 + for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_DCACHE_SIZE;
1.229 + addr += CONFIG_SYS_CACHELINE_SIZE) {
1.230 + asm volatile (
1.231 + ".set mips3\n\t"
1.232 + " cache %0, 0(%1)\n\t"
1.233 + ".set mips2\n\t"
1.234 + :
1.235 + : "I" (Index_Writeback_Inv_D), "r"(addr));
1.236 + }
1.237 +
1.238 + asm volatile ("sync");
1.239 +}
1.240 +
1.241 +void flush_cache_all(void)
1.242 +{
1.243 + flush_dcache_all();
1.244 + flush_icache_all();
1.245 +}