1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/board-nanonote2.c Sun Jun 07 18:21:24 2015 +0200
1.3 @@ -0,0 +1,334 @@
1.4 +/*
1.5 + * Ben NanoNote board late initialisation, based on uboot-xburst and xburst-tools.
1.6 + *
1.7 + * Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
1.8 + * Copyright (C) Xiangfu Liu <xiangfu.z@gmail.com>
1.9 + * Copyright (C) 2006 Ingenic Semiconductor, <jlwei@ingenic.cn>
1.10 + * Copyright (C) 2000-2009 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
1.11 + *
1.12 + * This program is free software; you can redistribute it and/or modify it under
1.13 + * the terms of the GNU General Public License as published by the Free Software
1.14 + * Foundation; either version 3 of the License, or (at your option) any later
1.15 + * version.
1.16 + *
1.17 + * This program is distributed in the hope that it will be useful, but WITHOUT
1.18 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.19 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.20 + * details.
1.21 + *
1.22 + * You should have received a copy of the GNU General Public License along with
1.23 + * this program. If not, see <http://www.gnu.org/licenses/>.
1.24 + */
1.25 +
1.26 +#include "jz4740.h"
1.27 +#include "configs.h"
1.28 +#include "nanonote.h"
1.29 +
1.30 +/* Later initialisation functions. */
1.31 +
1.32 +void gpio_init2(void)
1.33 +{
1.34 + /*
1.35 + * Initialize LCD pins
1.36 + */
1.37 + __gpio_as_slcd_8bit();
1.38 +
1.39 + /*
1.40 + * Initialize MSC pins
1.41 + */
1.42 + __gpio_as_msc();
1.43 +
1.44 + /*
1.45 + * Initialize Other pins
1.46 + */
1.47 + unsigned int i;
1.48 + for (i = 0; i < 7; i++){
1.49 + __gpio_as_input(GPIO_KEYIN_BASE + i);
1.50 + __gpio_enable_pull(GPIO_KEYIN_BASE + i);
1.51 + }
1.52 +
1.53 + for (i = 0; i < 8; i++) {
1.54 + __gpio_as_output(GPIO_KEYOUT_BASE + i);
1.55 + __gpio_clear_pin(GPIO_KEYOUT_BASE + i);
1.56 + }
1.57 +
1.58 + /* enable the TP4, TP5 as UART0 */
1.59 + __gpio_jtag_to_uart0();
1.60 +
1.61 + __gpio_as_input(GPIO_KEYIN_8);
1.62 + __gpio_enable_pull(GPIO_KEYIN_8);
1.63 +
1.64 + __gpio_as_output(GPIO_AUDIO_POP);
1.65 + __gpio_set_pin(GPIO_AUDIO_POP);
1.66 +
1.67 + __gpio_as_output(GPIO_LCD_CS);
1.68 + __gpio_clear_pin(GPIO_LCD_CS);
1.69 +
1.70 + __gpio_as_output(GPIO_AMP_EN);
1.71 + __gpio_clear_pin(GPIO_AMP_EN);
1.72 +
1.73 + __gpio_as_output(GPIO_SDPW_EN);
1.74 + __gpio_disable_pull(GPIO_SDPW_EN);
1.75 + __gpio_clear_pin(GPIO_SDPW_EN);
1.76 +
1.77 + __gpio_as_input(GPIO_SD_DETECT);
1.78 + __gpio_disable_pull(GPIO_SD_DETECT);
1.79 +
1.80 + __gpio_as_input(GPIO_USB_DETECT);
1.81 + __gpio_enable_pull(GPIO_USB_DETECT);
1.82 +}
1.83 +
1.84 +void cpm_init(void)
1.85 +{
1.86 + __cpm_stop_ipu();
1.87 + __cpm_stop_cim();
1.88 + __cpm_stop_i2c();
1.89 + __cpm_stop_ssi();
1.90 + __cpm_stop_uart1();
1.91 + __cpm_stop_sadc();
1.92 + __cpm_stop_uhc();
1.93 + __cpm_stop_udc();
1.94 + __cpm_stop_aic1();
1.95 +/* __cpm_stop_aic2();*/
1.96 +}
1.97 +
1.98 +void rtc_init(void)
1.99 +{
1.100 + while ( !__rtc_write_ready());
1.101 + __rtc_enable_alarm(); /* enable alarm */
1.102 +
1.103 + while ( !__rtc_write_ready());
1.104 + REG_RTC_RGR = 0x00007fff; /* type value */
1.105 +
1.106 + while ( !__rtc_write_ready());
1.107 + REG_RTC_HWFCR = 0x0000ffe0; /* Power on delay 2s */
1.108 +
1.109 + while ( !__rtc_write_ready());
1.110 + REG_RTC_HRCR = 0x00000fe0; /* reset delay 125ms */
1.111 +}
1.112 +
1.113 +unsigned long get_memory_size(void)
1.114 +{
1.115 + unsigned int dmcr;
1.116 + unsigned int rows, cols, dw, banks;
1.117 + unsigned long size;
1.118 +
1.119 + dmcr = REG_EMC_DMCR;
1.120 + rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT);
1.121 + cols = 8 + ((dmcr & EMC_DMCR_CA_MASK) >> EMC_DMCR_CA_BIT);
1.122 + dw = (dmcr & EMC_DMCR_BW) ? 2 : 4;
1.123 + banks = (dmcr & EMC_DMCR_BA) ? 4 : 2;
1.124 +
1.125 + size = (1 << (rows + cols)) * dw * banks;
1.126 +
1.127 + return size;
1.128 +}
1.129 +
1.130 +/* Timer routines. */
1.131 +
1.132 +#define TIMER_CHAN 0
1.133 +#define TIMER_FDATA 0xffff /* Timer full data value */
1.134 +#define TIMER_HZ CONFIG_SYS_HZ
1.135 +
1.136 +#define READ_TIMER REG_TCU_TCNT(TIMER_CHAN) /* macro to read the 16 bit timer */
1.137 +
1.138 +static unsigned long timestamp;
1.139 +static unsigned long lastdec;
1.140 +
1.141 +void reset_timer_masked(void);
1.142 +unsigned long get_timer_masked(void);
1.143 +void udelay_masked(unsigned long usec);
1.144 +
1.145 +/*
1.146 + * timer without interrupts
1.147 + */
1.148 +
1.149 +int timer_init(void)
1.150 +{
1.151 + REG_TCU_TCSR(TIMER_CHAN) = TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN;
1.152 + REG_TCU_TCNT(TIMER_CHAN) = 0;
1.153 + REG_TCU_TDHR(TIMER_CHAN) = 0;
1.154 + REG_TCU_TDFR(TIMER_CHAN) = TIMER_FDATA;
1.155 +
1.156 + REG_TCU_TMSR = (1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)); /* mask irqs */
1.157 + REG_TCU_TSCR = (1 << TIMER_CHAN); /* enable timer clock */
1.158 + REG_TCU_TESR = (1 << TIMER_CHAN); /* start counting up */
1.159 +
1.160 + lastdec = 0;
1.161 + timestamp = 0;
1.162 +
1.163 + return 0;
1.164 +}
1.165 +
1.166 +void reset_timer(void)
1.167 +{
1.168 + reset_timer_masked ();
1.169 +}
1.170 +
1.171 +unsigned long get_timer(unsigned long base)
1.172 +{
1.173 + return get_timer_masked () - base;
1.174 +}
1.175 +
1.176 +void set_timer(unsigned long t)
1.177 +{
1.178 + timestamp = t;
1.179 +}
1.180 +
1.181 +void udelay (unsigned long usec)
1.182 +{
1.183 + unsigned long tmo,tmp;
1.184 +
1.185 + /* normalize */
1.186 + if (usec >= 1000) {
1.187 + tmo = usec / 1000;
1.188 + tmo *= TIMER_HZ;
1.189 + tmo /= 1000;
1.190 + }
1.191 + else {
1.192 + if (usec >= 1) {
1.193 + tmo = usec * TIMER_HZ;
1.194 + tmo /= (1000*1000);
1.195 + }
1.196 + else
1.197 + tmo = 1;
1.198 + }
1.199 +
1.200 + /* check for rollover during this delay */
1.201 + tmp = get_timer (0);
1.202 + if ((tmp + tmo) < tmp )
1.203 + reset_timer_masked(); /* timer would roll over */
1.204 + else
1.205 + tmo += tmp;
1.206 +
1.207 + while (get_timer_masked () < tmo);
1.208 +}
1.209 +
1.210 +void reset_timer_masked (void)
1.211 +{
1.212 + /* reset time */
1.213 + lastdec = READ_TIMER;
1.214 + timestamp = 0;
1.215 +}
1.216 +
1.217 +unsigned long get_timer_masked (void)
1.218 +{
1.219 + unsigned long now = READ_TIMER;
1.220 +
1.221 + if (lastdec <= now) {
1.222 + /* normal mode */
1.223 + timestamp += (now - lastdec);
1.224 + } else {
1.225 + /* we have an overflow ... */
1.226 + timestamp += TIMER_FDATA + now - lastdec;
1.227 + }
1.228 + lastdec = now;
1.229 +
1.230 + return timestamp;
1.231 +}
1.232 +
1.233 +void udelay_masked (unsigned long usec)
1.234 +{
1.235 + unsigned long tmo;
1.236 + unsigned long endtime;
1.237 + signed long diff;
1.238 +
1.239 + /* normalize */
1.240 + if (usec >= 1000) {
1.241 + tmo = usec / 1000;
1.242 + tmo *= TIMER_HZ;
1.243 + tmo /= 1000;
1.244 + } else {
1.245 + if (usec > 1) {
1.246 + tmo = usec * TIMER_HZ;
1.247 + tmo /= (1000*1000);
1.248 + } else {
1.249 + tmo = 1;
1.250 + }
1.251 + }
1.252 +
1.253 + endtime = get_timer_masked () + tmo;
1.254 +
1.255 + do {
1.256 + unsigned long now = get_timer_masked ();
1.257 + diff = endtime - now;
1.258 + } while (diff >= 0);
1.259 +}
1.260 +
1.261 +/*
1.262 + * This function is derived from PowerPC code (read timebase as long long).
1.263 + * On MIPS it just returns the timer value.
1.264 + */
1.265 +unsigned long long get_ticks(void)
1.266 +{
1.267 + return get_timer(0);
1.268 +}
1.269 +
1.270 +/*
1.271 + * This function is derived from PowerPC code (timebase clock frequency).
1.272 + * On MIPS it returns the number of timer ticks per second.
1.273 + */
1.274 +unsigned long get_tbclk (void)
1.275 +{
1.276 + return TIMER_HZ;
1.277 +}
1.278 +
1.279 +/* CPU-specific routines from U-Boot.
1.280 + See: uboot-xburst/files/arch/mips/cpu/xburst/cpu.c
1.281 + See: u-boot/arch/mips/include/asm/cacheops.h
1.282 +*/
1.283 +
1.284 +#define Index_Store_Tag_I 0x08
1.285 +#define Index_Writeback_Inv_D 0x15
1.286 +
1.287 +void flush_icache_all(void)
1.288 +{
1.289 + u32 addr, t = 0;
1.290 +
1.291 + asm volatile ("mtc0 $0, $28"); /* Clear Taglo */
1.292 + asm volatile ("mtc0 $0, $29"); /* Clear TagHi */
1.293 +
1.294 + for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_ICACHE_SIZE;
1.295 + addr += CONFIG_SYS_CACHELINE_SIZE) {
1.296 + asm volatile (
1.297 + ".set mips3\n\t"
1.298 + " cache %0, 0(%1)\n\t"
1.299 + ".set mips2\n\t"
1.300 + :
1.301 + : "I" (Index_Store_Tag_I), "r"(addr));
1.302 + }
1.303 +
1.304 + /* invalicate btb */
1.305 + asm volatile (
1.306 + ".set mips32\n\t"
1.307 + "mfc0 %0, $16, 7\n\t"
1.308 + "nop\n\t"
1.309 + "ori %0,2\n\t"
1.310 + "mtc0 %0, $16, 7\n\t"
1.311 + ".set mips2\n\t"
1.312 + :
1.313 + : "r" (t));
1.314 +}
1.315 +
1.316 +void flush_dcache_all(void)
1.317 +{
1.318 + u32 addr;
1.319 +
1.320 + for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_DCACHE_SIZE;
1.321 + addr += CONFIG_SYS_CACHELINE_SIZE) {
1.322 + asm volatile (
1.323 + ".set mips3\n\t"
1.324 + " cache %0, 0(%1)\n\t"
1.325 + ".set mips2\n\t"
1.326 + :
1.327 + : "I" (Index_Writeback_Inv_D), "r"(addr));
1.328 + }
1.329 +
1.330 + asm volatile ("sync");
1.331 +}
1.332 +
1.333 +void flush_cache_all(void)
1.334 +{
1.335 + flush_dcache_all();
1.336 + flush_icache_all();
1.337 +}