1 /* 2 * Ben NanoNote board late initialisation, based on uboot-xburst and xburst-tools. 3 * 4 * Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk> 5 * Copyright (C) Xiangfu Liu <xiangfu.z@gmail.com> 6 * Copyright (C) 2006 Ingenic Semiconductor, <jlwei@ingenic.cn> 7 * Copyright (C) 2000-2009 Wolfgang Denk, DENX Software Engineering, <wd@denx.de> 8 * 9 * This program is free software; you can redistribute it and/or modify it under 10 * the terms of the GNU General Public License as published by the Free Software 11 * Foundation; either version 3 of the License, or (at your option) any later 12 * version. 13 * 14 * This program is distributed in the hope that it will be useful, but WITHOUT 15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 17 * details. 18 * 19 * You should have received a copy of the GNU General Public License along with 20 * this program. If not, see <http://www.gnu.org/licenses/>. 21 */ 22 23 #include "jz4740.h" 24 #include "nanonote.h" 25 26 /* Later initialisation functions. */ 27 28 void gpio_init2(void) 29 { 30 /* 31 * Initialize LCD pins 32 */ 33 __gpio_as_slcd_8bit(); 34 35 /* 36 * Initialize MSC pins 37 */ 38 __gpio_as_msc(); 39 40 /* 41 * Initialize Other pins 42 */ 43 unsigned int i; 44 for (i = 0; i < 7; i++){ 45 __gpio_as_input(GPIO_KEYIN_BASE + i); 46 __gpio_enable_pull(GPIO_KEYIN_BASE + i); 47 } 48 49 for (i = 0; i < 8; i++) { 50 __gpio_as_output(GPIO_KEYOUT_BASE + i); 51 __gpio_clear_pin(GPIO_KEYOUT_BASE + i); 52 } 53 54 /* enable the TP4, TP5 as UART0 */ 55 __gpio_jtag_to_uart0(); 56 57 __gpio_as_input(GPIO_KEYIN_8); 58 __gpio_enable_pull(GPIO_KEYIN_8); 59 60 __gpio_as_output(GPIO_AUDIO_POP); 61 __gpio_set_pin(GPIO_AUDIO_POP); 62 63 __gpio_as_output(GPIO_LCD_CS); 64 __gpio_clear_pin(GPIO_LCD_CS); 65 66 __gpio_as_output(GPIO_AMP_EN); 67 __gpio_clear_pin(GPIO_AMP_EN); 68 69 __gpio_as_output(GPIO_SDPW_EN); 70 __gpio_disable_pull(GPIO_SDPW_EN); 71 __gpio_clear_pin(GPIO_SDPW_EN); 72 73 __gpio_as_input(GPIO_SD_DETECT); 74 __gpio_disable_pull(GPIO_SD_DETECT); 75 76 __gpio_as_input(GPIO_USB_DETECT); 77 __gpio_enable_pull(GPIO_USB_DETECT); 78 } 79 80 void cpm_init(void) 81 { 82 __cpm_stop_ipu(); 83 __cpm_stop_cim(); 84 __cpm_stop_i2c(); 85 __cpm_stop_ssi(); 86 __cpm_stop_uart1(); 87 __cpm_stop_sadc(); 88 __cpm_stop_uhc(); 89 __cpm_stop_udc(); 90 __cpm_stop_aic1(); 91 /* __cpm_stop_aic2();*/ 92 } 93 94 void rtc_init(void) 95 { 96 while ( !__rtc_write_ready()); 97 __rtc_enable_alarm(); /* enable alarm */ 98 99 while ( !__rtc_write_ready()); 100 REG_RTC_RGR = 0x00007fff; /* type value */ 101 102 while ( !__rtc_write_ready()); 103 REG_RTC_HWFCR = 0x0000ffe0; /* Power on delay 2s */ 104 105 while ( !__rtc_write_ready()); 106 REG_RTC_HRCR = 0x00000fe0; /* reset delay 125ms */ 107 } 108 109 unsigned long get_memory_size(void) 110 { 111 unsigned int dmcr; 112 unsigned int rows, cols, dw, banks; 113 unsigned long size; 114 115 dmcr = REG_EMC_DMCR; 116 rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT); 117 cols = 8 + ((dmcr & EMC_DMCR_CA_MASK) >> EMC_DMCR_CA_BIT); 118 dw = (dmcr & EMC_DMCR_BW) ? 2 : 4; 119 banks = (dmcr & EMC_DMCR_BA) ? 4 : 2; 120 121 size = (1 << (rows + cols)) * dw * banks; 122 123 return size; 124 } 125 126 /* Timer routines. */ 127 128 #define TIMER_CHAN 0 129 #define TIMER_FDATA 0xffff /* Timer full data value */ 130 #define TIMER_HZ CONFIG_SYS_HZ 131 132 #define READ_TIMER REG_TCU_TCNT(TIMER_CHAN) /* macro to read the 16 bit timer */ 133 134 static unsigned long timestamp; 135 static unsigned long lastdec; 136 137 void reset_timer_masked(void); 138 unsigned long get_timer_masked(void); 139 void udelay_masked(unsigned long usec); 140 141 /* 142 * timer without interrupts 143 */ 144 145 int timer_init(void) 146 { 147 REG_TCU_TCSR(TIMER_CHAN) = TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN; 148 REG_TCU_TCNT(TIMER_CHAN) = 0; 149 REG_TCU_TDHR(TIMER_CHAN) = 0; 150 REG_TCU_TDFR(TIMER_CHAN) = TIMER_FDATA; 151 152 REG_TCU_TMSR = (1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)); /* mask irqs */ 153 REG_TCU_TSCR = (1 << TIMER_CHAN); /* enable timer clock */ 154 REG_TCU_TESR = (1 << TIMER_CHAN); /* start counting up */ 155 156 lastdec = 0; 157 timestamp = 0; 158 159 return 0; 160 } 161 162 void reset_timer(void) 163 { 164 reset_timer_masked (); 165 } 166 167 unsigned long get_timer(unsigned long base) 168 { 169 return get_timer_masked () - base; 170 } 171 172 void set_timer(unsigned long t) 173 { 174 timestamp = t; 175 } 176 177 void udelay (unsigned long usec) 178 { 179 unsigned long tmo,tmp; 180 181 /* normalize */ 182 if (usec >= 1000) { 183 tmo = usec / 1000; 184 tmo *= TIMER_HZ; 185 tmo /= 1000; 186 } 187 else { 188 if (usec >= 1) { 189 tmo = usec * TIMER_HZ; 190 tmo /= (1000*1000); 191 } 192 else 193 tmo = 1; 194 } 195 196 /* check for rollover during this delay */ 197 tmp = get_timer (0); 198 if ((tmp + tmo) < tmp ) 199 reset_timer_masked(); /* timer would roll over */ 200 else 201 tmo += tmp; 202 203 while (get_timer_masked () < tmo); 204 } 205 206 void reset_timer_masked (void) 207 { 208 /* reset time */ 209 lastdec = READ_TIMER; 210 timestamp = 0; 211 } 212 213 unsigned long get_timer_masked (void) 214 { 215 unsigned long now = READ_TIMER; 216 217 if (lastdec <= now) { 218 /* normal mode */ 219 timestamp += (now - lastdec); 220 } else { 221 /* we have an overflow ... */ 222 timestamp += TIMER_FDATA + now - lastdec; 223 } 224 lastdec = now; 225 226 return timestamp; 227 } 228 229 void udelay_masked (unsigned long usec) 230 { 231 unsigned long tmo; 232 unsigned long endtime; 233 signed long diff; 234 235 /* normalize */ 236 if (usec >= 1000) { 237 tmo = usec / 1000; 238 tmo *= TIMER_HZ; 239 tmo /= 1000; 240 } else { 241 if (usec > 1) { 242 tmo = usec * TIMER_HZ; 243 tmo /= (1000*1000); 244 } else { 245 tmo = 1; 246 } 247 } 248 249 endtime = get_timer_masked () + tmo; 250 251 do { 252 unsigned long now = get_timer_masked (); 253 diff = endtime - now; 254 } while (diff >= 0); 255 } 256 257 /* 258 * This function is derived from PowerPC code (read timebase as long long). 259 * On MIPS it just returns the timer value. 260 */ 261 unsigned long long get_ticks(void) 262 { 263 return get_timer(0); 264 } 265 266 /* 267 * This function is derived from PowerPC code (timebase clock frequency). 268 * On MIPS it returns the number of timer ticks per second. 269 */ 270 unsigned long get_tbclk (void) 271 { 272 return TIMER_HZ; 273 } 274 275 /* CPU-specific routines from U-Boot. 276 See: uboot-xburst/files/arch/mips/cpu/xburst/cpu.c 277 See: u-boot/arch/mips/include/asm/cacheops.h 278 */ 279 280 #define Index_Store_Tag_I 0x08 281 #define Index_Writeback_Inv_D 0x15 282 283 void flush_icache_all(void) 284 { 285 u32 addr, t = 0; 286 287 asm volatile ("mtc0 $0, $28"); /* Clear Taglo */ 288 asm volatile ("mtc0 $0, $29"); /* Clear TagHi */ 289 290 for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_ICACHE_SIZE; 291 addr += CONFIG_SYS_CACHELINE_SIZE) { 292 asm volatile ( 293 ".set mips3\n\t" 294 " cache %0, 0(%1)\n\t" 295 ".set mips2\n\t" 296 : 297 : "I" (Index_Store_Tag_I), "r"(addr)); 298 } 299 300 /* invalicate btb */ 301 asm volatile ( 302 ".set mips32\n\t" 303 "mfc0 %0, $16, 7\n\t" 304 "nop\n\t" 305 "ori %0,2\n\t" 306 "mtc0 %0, $16, 7\n\t" 307 ".set mips2\n\t" 308 : 309 : "r" (t)); 310 } 311 312 void flush_dcache_all(void) 313 { 314 u32 addr; 315 316 for (addr = KSEG0; addr < KSEG0 + CONFIG_SYS_DCACHE_SIZE; 317 addr += CONFIG_SYS_CACHELINE_SIZE) { 318 asm volatile ( 319 ".set mips3\n\t" 320 " cache %0, 0(%1)\n\t" 321 ".set mips2\n\t" 322 : 323 : "I" (Index_Writeback_Inv_D), "r"(addr)); 324 } 325 326 asm volatile ("sync"); 327 } 328 329 void flush_cache_all(void) 330 { 331 flush_dcache_all(); 332 flush_icache_all(); 333 }