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