Move c/h files implementing/defining standard library stuff into a new libc directory...
[kugel-rb.git] / firmware / target / mips / ingenic_jz47xx / system-jz4740.c
blob588cc16aea6b35ba55639b95838299bccf2ecaaf
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2008 by Maurus Cuelenaere
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "config.h"
23 #include "jz4740.h"
24 #include "mips.h"
25 #include "mmu-mips.h"
26 #include "panic.h"
27 #include "system.h"
28 #include "kernel.h"
30 #define EXTENDED_EXCEPTION_DESC 0
31 #if EXTENDED_EXCEPTION_DESC
32 #include "backlight-target.h"
33 #include "font.h"
34 #include "lcd.h"
35 #endif
37 #define NUM_DMA 6
38 #define NUM_GPIO 128
39 #define IRQ_MAX (IRQ_GPIO_0 + NUM_GPIO)
41 static int irq;
42 static void UIRQ(void)
44 panicf("Unhandled interrupt occurred: %d", irq);
47 #define intr(name) extern __attribute__((weak,alias("UIRQ"))) void name (void)
49 intr(I2C);intr(EMC);intr(UHC);intr(UART0);intr(SADC);intr(MSC);intr(RTC);
50 intr(SSI);intr(CIM);intr(AIC);intr(ETH);intr(TCU2);intr(TCU1);intr(TCU0);
51 intr(UDC);intr(IPU);intr(LCD);
53 intr(DMA0);intr(DMA1);intr(DMA2);intr(DMA3);intr(DMA4);intr(DMA5);
55 intr(GPIO0);intr(GPIO1);intr(GPIO2);intr(GPIO3);intr(GPIO4);intr(GPIO5);
56 intr(GPIO6);intr(GPIO7);intr(GPIO8);intr(GPIO9);intr(GPIO10);intr(GPIO11);
57 intr(GPIO12);intr(GPIO13);intr(GPIO14);intr(GPIO15);intr(GPIO16);intr(GPIO17);
58 intr(GPIO18);intr(GPIO19);intr(GPIO20);intr(GPIO21);intr(GPIO22);intr(GPIO23);
59 intr(GPIO24);intr(GPIO25);intr(GPIO26);intr(GPIO27);intr(GPIO28);intr(GPIO29);
60 intr(GPIO30);intr(GPIO31);intr(GPIO32);intr(GPIO33);intr(GPIO34);intr(GPIO35);
61 intr(GPIO36);intr(GPIO37);intr(GPIO38);intr(GPIO39);intr(GPIO40);intr(GPIO41);
62 intr(GPIO42);intr(GPIO43);intr(GPIO44);intr(GPIO45);intr(GPIO46);intr(GPIO47);
63 intr(GPIO48);intr(GPIO49);intr(GPIO50);intr(GPIO51);intr(GPIO52);intr(GPIO53);
64 intr(GPIO54);intr(GPIO55);intr(GPIO56);intr(GPIO57);intr(GPIO58);intr(GPIO59);
65 intr(GPIO60);intr(GPIO61);intr(GPIO62);intr(GPIO63);intr(GPIO64);intr(GPIO65);
66 intr(GPIO66);intr(GPIO67);intr(GPIO68);intr(GPIO69);intr(GPIO70);intr(GPIO71);
67 intr(GPIO72);intr(GPIO73);intr(GPIO74);intr(GPIO75);intr(GPIO76);intr(GPIO77);
68 intr(GPIO78);intr(GPIO79);intr(GPIO80);intr(GPIO81);intr(GPIO82);intr(GPIO83);
69 intr(GPIO84);intr(GPIO85);intr(GPIO86);intr(GPIO87);intr(GPIO88);intr(GPIO89);
70 intr(GPIO90);intr(GPIO91);intr(GPIO92);intr(GPIO93);intr(GPIO94);intr(GPIO95);
71 intr(GPIO96);intr(GPIO97);intr(GPIO98);intr(GPIO99);intr(GPIO100);intr(GPIO101);
72 intr(GPIO102);intr(GPIO103);intr(GPIO104);intr(GPIO105);intr(GPIO106);
73 intr(GPIO107);intr(GPIO108);intr(GPIO109);intr(GPIO110);intr(GPIO111);
74 intr(GPIO112);intr(GPIO113);intr(GPIO114);intr(GPIO115);intr(GPIO116);
75 intr(GPIO117);intr(GPIO118);intr(GPIO119);intr(GPIO120);intr(GPIO121);
76 intr(GPIO122);intr(GPIO123);intr(GPIO124);intr(GPIO125);intr(GPIO126);
77 intr(GPIO127);
79 static void (* const irqvector[])(void) =
81 I2C,EMC,UHC,UIRQ,UIRQ,UIRQ,UIRQ,UIRQ,
82 UART0,UIRQ,UIRQ,SADC,UIRQ,MSC,RTC,SSI,
83 CIM,AIC,ETH,UIRQ,TCU2,TCU1,TCU0,UDC,
84 UIRQ,UIRQ,UIRQ,UIRQ,IPU,LCD,UIRQ,DMA0,
85 DMA1,DMA2,DMA3,DMA4,DMA5,UIRQ,UIRQ,UIRQ,
86 UIRQ,UIRQ,UIRQ,UIRQ,UIRQ,UIRQ,UIRQ,
87 GPIO0,GPIO1,GPIO2,GPIO3,GPIO4,GPIO5,GPIO6,GPIO7,
88 GPIO8,GPIO9,GPIO10,GPIO11,GPIO12,GPIO13,GPIO14,GPIO15,
89 GPIO16,GPIO17,GPIO18,GPIO19,GPIO20,GPIO21,GPIO22,GPIO23,
90 GPIO24,GPIO25,GPIO26,GPIO27,GPIO28,GPIO29,GPIO30,GPIO31,
91 GPIO32,GPIO33,GPIO34,GPIO35,GPIO36,GPIO37,GPIO38,GPIO39,
92 GPIO40,GPIO41,GPIO42,GPIO43,GPIO44,GPIO45,GPIO46,GPIO47,
93 GPIO48,GPIO49,GPIO50,GPIO51,GPIO52,GPIO53,GPIO54,GPIO55,
94 GPIO56,GPIO57,GPIO58,GPIO59,GPIO60,GPIO61,GPIO62,GPIO63,
95 GPIO64,GPIO65,GPIO66,GPIO67,GPIO68,GPIO69,GPIO70,GPIO71,
96 GPIO72,GPIO73,GPIO74,GPIO75,GPIO76,GPIO77,GPIO78,GPIO79,
97 GPIO80,GPIO81,GPIO82,GPIO83,GPIO84,GPIO85,GPIO86,GPIO87,
98 GPIO88,GPIO89,GPIO90,GPIO91,GPIO92,GPIO93,GPIO94,GPIO95,
99 GPIO96,GPIO97,GPIO98,GPIO99,GPIO100,GPIO101,GPIO102,GPIO103,
100 GPIO104,GPIO105,GPIO106,GPIO107,GPIO108,GPIO109,GPIO110,GPIO111,
101 GPIO112,GPIO113,GPIO114,GPIO115,GPIO116,GPIO117,GPIO118,GPIO119,
102 GPIO120,GPIO121,GPIO122,GPIO123,GPIO124,GPIO125,GPIO126,GPIO127
105 static unsigned int dma_irq_mask = 0;
106 static unsigned int gpio_irq_mask[4] = {0};
108 void system_enable_irq(unsigned int irq)
110 register unsigned int t;
111 if ((irq >= IRQ_GPIO_0) && (irq <= IRQ_GPIO_0 + NUM_GPIO))
113 __gpio_unmask_irq(irq - IRQ_GPIO_0);
114 t = (irq - IRQ_GPIO_0) >> 5;
115 gpio_irq_mask[t] |= (1 << ((irq - IRQ_GPIO_0) & 0x1f));
116 __intc_unmask_irq(IRQ_GPIO0 - t);
118 else if ((irq >= IRQ_DMA_0) && (irq <= IRQ_DMA_0 + NUM_DMA))
120 __dmac_channel_enable_irq(irq - IRQ_DMA_0);
121 dma_irq_mask |= (1 << (irq - IRQ_DMA_0));
122 __intc_unmask_irq(IRQ_DMAC);
124 else if (irq < 32)
125 __intc_unmask_irq(irq);
128 static void dis_irq(unsigned int irq)
130 register unsigned int t;
131 if ((irq >= IRQ_GPIO_0) && (irq <= IRQ_GPIO_0 + NUM_GPIO))
133 __gpio_mask_irq(irq - IRQ_GPIO_0);
134 t = (irq - IRQ_GPIO_0) >> 5;
135 gpio_irq_mask[t] &= ~(1 << ((irq - IRQ_GPIO_0) & 0x1f));
136 if (!gpio_irq_mask[t])
137 __intc_mask_irq(IRQ_GPIO0 - t);
139 else if ((irq >= IRQ_DMA_0) && (irq <= IRQ_DMA_0 + NUM_DMA))
141 __dmac_channel_disable_irq(irq - IRQ_DMA_0);
142 dma_irq_mask &= ~(1 << (irq - IRQ_DMA_0));
143 if (!dma_irq_mask)
144 __intc_mask_irq(IRQ_DMAC);
146 else if (irq < 32)
147 __intc_mask_irq(irq);
150 static void ack_irq(unsigned int irq)
152 if ((irq >= IRQ_GPIO_0) && (irq <= IRQ_GPIO_0 + NUM_GPIO))
154 __intc_ack_irq(IRQ_GPIO0 - ((irq - IRQ_GPIO_0)>>5));
155 __gpio_ack_irq(irq - IRQ_GPIO_0);
157 else if ((irq >= IRQ_DMA_0) && (irq <= IRQ_DMA_0 + NUM_DMA))
158 __intc_ack_irq(IRQ_DMAC);
159 else if (irq < 32)
160 __intc_ack_irq(irq);
163 static int get_irq_number(void)
165 static unsigned long ipl;
166 register int irq;
168 ipl |= REG_INTC_IPR;
170 if (UNLIKELY(ipl == 0))
171 return -1;
173 __asm__ __volatile__("negu $8, %0 \n"
174 "and $8, %0, $8 \n"
175 "clz %0, %1 \n"
176 "li $8, 31 \n"
177 "subu %0, $8, %0 \n"
178 : "=r" (irq)
179 : "r" (ipl)
180 : "t0"
183 if (UNLIKELY(irq < 0))
184 return -1;
186 ipl &= ~(1 << irq);
188 switch (irq)
190 case IRQ_GPIO0:
191 irq = __gpio_group_irq(0) + IRQ_GPIO_0;
192 break;
193 case IRQ_GPIO1:
194 irq = __gpio_group_irq(1) + IRQ_GPIO_0 + 32;
195 break;
196 case IRQ_GPIO2:
197 irq = __gpio_group_irq(2) + IRQ_GPIO_0 + 64;
198 break;
199 case IRQ_GPIO3:
200 irq = __gpio_group_irq(3) + IRQ_GPIO_0 + 96;
201 break;
202 case IRQ_DMAC:
203 irq = __dmac_get_irq() + IRQ_DMA_0;
204 break;
207 return irq;
210 void intr_handler(void)
212 register int irq = get_irq_number();
213 if(UNLIKELY(irq < 0))
214 return;
216 ack_irq(irq);
217 if(LIKELY(irq > 0))
218 irqvector[irq-1]();
221 #define EXC(x,y) case (x): return (y);
222 static char* parse_exception(unsigned int cause)
224 switch(cause & M_CauseExcCode)
226 EXC(EXC_INT, "Interrupt");
227 EXC(EXC_MOD, "TLB Modified");
228 EXC(EXC_TLBL, "TLB Exception (Load or Ifetch)");
229 EXC(EXC_ADEL, "Address Error (Load or Ifetch)");
230 EXC(EXC_ADES, "Address Error (Store)");
231 EXC(EXC_TLBS, "TLB Exception (Store)");
232 EXC(EXC_IBE, "Instruction Bus Error");
233 EXC(EXC_DBE, "Data Bus Error");
234 EXC(EXC_SYS, "Syscall");
235 EXC(EXC_BP, "Breakpoint");
236 EXC(EXC_RI, "Reserved Instruction");
237 EXC(EXC_CPU, "Coprocessor Unusable");
238 EXC(EXC_OV, "Overflow");
239 EXC(EXC_TR, "Trap Instruction");
240 EXC(EXC_FPE, "Floating Point Exception");
241 EXC(EXC_C2E, "COP2 Exception");
242 EXC(EXC_MDMX, "MDMX Exception");
243 EXC(EXC_WATCH, "Watch Exception");
244 EXC(EXC_MCHECK, "Machine Check Exception");
245 EXC(EXC_CacheErr, "Cache error caused re-entry to Debug Mode");
246 default:
247 return NULL;
251 void exception_handler(void* stack_ptr, unsigned int cause, unsigned int epc)
253 #if EXTENDED_EXCEPTION_DESC
254 (void)epc;
256 /* Depends on crt0.S ! */
257 char *registers[] = { "ra", "fp", "gp", "t9", "t8", "s7", "s6", "s5", "s4",
258 "s3", "s2", "s1", "s0", "t7", "t6", "t5", "t4", "t3",
259 "t2", "t1", "t0", "a3", "a2", "a1", "a0", "v1", "v0",
260 "$1", "LO", "HI", "STATUS", "EPC" };
261 int i;
263 #ifdef HAVE_LCD_BITMAP
264 #if LCD_DEPTH > 1
265 lcd_set_backdrop(NULL);
266 lcd_set_drawmode(DRMODE_SOLID);
267 lcd_set_foreground(LCD_BLACK);
268 lcd_set_background(LCD_WHITE);
269 #endif
270 lcd_setfont(FONT_SYSFIXED);
271 lcd_set_viewport(NULL);
272 #endif
273 lcd_clear_display();
274 _backlight_on();
276 lcd_puts(0, 0, parse_exception(cause));
277 lcd_putsf(0, 1, "0x%08x at 0x%08x", read_c0_badvaddr(), epc);
278 for(i=0; i< 0x80/4; i+=2)
280 unsigned int* ptr = (unsigned int*)(stack_ptr + i*4);
281 lcd_putsf(0, 3 + i/2, "%s: 0x%08x %s: 0x%08x", registers[i], *ptr, registers[i+1], *(ptr+1));
283 lcd_update();
285 system_exception_wait();
286 #else
287 panicf("Exception occurred: %s [0x%08x] at 0x%08x (stack at 0x%08x)", parse_exception(cause), read_c0_badvaddr(), epc, (unsigned int)stack_ptr);
288 #endif
291 void tlb_refill_handler(void)
293 panicf("TLB refill handler at 0x%08lx! [0x%x]", read_c0_epc(), read_c0_badvaddr());
296 void udelay(unsigned int usec)
298 unsigned int i = usec * (__cpm_get_cclk() / 2000000);
299 __asm__ __volatile__ (
300 ".set noreorder \n"
301 "1: \n"
302 "bne %0, $0, 1b \n"
303 "addi %0, %0, -1 \n"
304 ".set reorder \n"
305 : "=r" (i)
306 : "0" (i)
310 void mdelay(unsigned int msec)
312 unsigned int i;
313 for(i=0; i<msec; i++)
314 udelay(1000);
317 static int dma_count = 0;
318 void dma_enable(void)
320 if(++dma_count == 1)
322 __cpm_start_dmac();
324 REG_DMAC_DCCSR(0) = 0;
325 REG_DMAC_DCCSR(1) = 0;
326 REG_DMAC_DCCSR(2) = 0;
327 REG_DMAC_DCCSR(3) = 0;
328 REG_DMAC_DCCSR(4) = 0;
329 REG_DMAC_DCCSR(5) = 0;
331 REG_DMAC_DMACR = (DMAC_DMACR_PR_RR | DMAC_DMACR_DMAE);
335 void dma_disable(void)
337 if(--dma_count == 0)
339 REG_DMAC_DMACR &= ~DMAC_DMACR_DMAE;
340 __cpm_stop_dmac();
344 /* PLL output clock = EXTAL * NF / (NR * NO)
346 * NF = FD + 2, NR = RD + 2
347 * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3)
349 static void pll_init(void) ICODE_ATTR;
350 static void pll_init(void)
352 register unsigned int cfcr, plcr1;
353 int n2FR[33] = {
354 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
355 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
358 int div[5] = {0, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
359 int nf, pllout2;
361 cfcr = CPM_CPCCR_CLKOEN |
362 CPM_CPCCR_PCS |
363 (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
364 (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
365 (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
366 (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
367 (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT) |
368 CPM_CPCCR_CE; /* Perform clock divisions immediately */
370 pllout2 = (cfcr & CPM_CPCCR_PCS) ? CPU_FREQ : (CPU_FREQ / 2);
372 /* Init USB Host clock, pllout2 must be n*48MHz */
373 REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
375 nf = CPU_FREQ * 2 / CFG_EXTAL;
376 plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
377 (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
378 (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
379 (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
380 CPM_CPPCR_PLLEN; /* enable PLL */
382 /* init PLL */
383 REG_CPM_CPCCR = cfcr;
384 REG_CPM_CPPCR = plcr1;
387 // SDRAM paramters
388 #define CFG_SDRAM_BW16 0 /* Data bus width: 0-32bit, 1-16bit */
389 #define CFG_SDRAM_BANK4 1 /* Banks each chip: 0-2bank, 1-4bank */
390 #define CFG_SDRAM_ROW 12 /* Row address: 11 to 13 */
391 #define CFG_SDRAM_COL 8 /* Column address: 8 to 12 */
392 #define CFG_SDRAM_CASL 2 /* CAS latency: 2 or 3 */
394 // SDRAM Timings, unit: ns
395 #define CFG_SDRAM_TRAS 45 /* RAS# Active Time */
396 #define CFG_SDRAM_RCD 20 /* RAS# to CAS# Delay */
397 #define CFG_SDRAM_TPC 20 /* RAS# Precharge Time */
398 #define CFG_SDRAM_TRWL 7 /* Write Latency Time */
399 #define CFG_SDRAM_TREF 7812 /* Refresh period: 8192 refresh cycles/64ms */
402 * Init SDRAM memory.
404 static void sdram_init(void) ICODE_ATTR;
405 static void sdram_init(void)
407 register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
409 unsigned int cas_latency_sdmr[2] = {
410 EMC_SDMR_CAS_2,
411 EMC_SDMR_CAS_3,
414 unsigned int cas_latency_dmcr[2] = {
415 1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */
416 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
419 int div[] = { 1, 2, 3, 4, 6, 8, 12, 16, 24, 32 };
421 cpu_clk = CPU_FREQ;
422 mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
424 //REG_EMC_BCR = 0; /* Disable bus release */
425 REG_EMC_RTCSR = 0; /* Disable clock for counting */
426 REG_EMC_RTCOR = 0;
427 REG_EMC_RTCNT = 0;
429 /* Fault DMCR value for mode register setting */
430 #define SDRAM_ROW0 11
431 #define SDRAM_COL0 8
432 #define SDRAM_BANK40 0
434 dmcr0 = ((SDRAM_ROW0 - 11) << EMC_DMCR_RA_BIT) |
435 ((SDRAM_COL0 - 8) << EMC_DMCR_CA_BIT) |
436 (SDRAM_BANK40 << EMC_DMCR_BA_BIT) |
437 (CFG_SDRAM_BW16 << EMC_DMCR_BW_BIT) |
438 EMC_DMCR_EPIN | cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
440 /* Basic DMCR value */
441 dmcr = ((CFG_SDRAM_ROW - 11) << EMC_DMCR_RA_BIT) |
442 ((CFG_SDRAM_COL - 8) << EMC_DMCR_CA_BIT) |
443 (CFG_SDRAM_BANK4 << EMC_DMCR_BA_BIT) |
444 (CFG_SDRAM_BW16 << EMC_DMCR_BW_BIT) |
445 EMC_DMCR_EPIN | cas_latency_dmcr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
447 /* SDRAM timimg */
448 ns = 1000000000 / mem_clk;
449 tmp = CFG_SDRAM_TRAS / ns;
450 if (tmp < 4)
451 tmp = 4;
452 if (tmp > 11)
453 tmp = 11;
454 dmcr |= ((tmp - 4) << EMC_DMCR_TRAS_BIT);
455 tmp = CFG_SDRAM_RCD / ns;
456 if (tmp > 3)
457 tmp = 3;
458 dmcr |= (tmp << EMC_DMCR_RCD_BIT);
459 tmp = CFG_SDRAM_TPC / ns;
460 if (tmp > 7)
461 tmp = 7;
462 dmcr |= (tmp << EMC_DMCR_TPC_BIT);
463 tmp = CFG_SDRAM_TRWL / ns;
464 if (tmp > 3)
465 tmp = 3;
466 dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
467 tmp = (CFG_SDRAM_TRAS + CFG_SDRAM_TPC) / ns;
468 if (tmp > 14)
469 tmp = 14;
470 dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
472 /* SDRAM mode value */
473 sdmode = EMC_SDMR_BT_SEQ |
474 EMC_SDMR_OM_NORMAL |
475 EMC_SDMR_BL_4 | cas_latency_sdmr[((CFG_SDRAM_CASL == 3) ? 1 : 0)];
477 /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
478 REG_EMC_DMCR = dmcr;
479 REG8(EMC_SDMR0 | sdmode) = 0;
481 /* Wait for precharge, > 200us */
482 tmp = (cpu_clk / 1000000) * 1000;
483 while (tmp--);
485 /* Stage 2. Enable auto-refresh */
486 REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;
488 tmp = CFG_SDRAM_TREF / ns;
489 tmp = tmp / 64 + 1;
490 if (tmp > 0xff)
491 tmp = 0xff;
492 REG_EMC_RTCOR = tmp;
493 REG_EMC_RTCNT = 0;
494 REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */
496 /* Wait for number of auto-refresh cycles */
497 tmp = (cpu_clk / 1000000) * 1000;
498 while (tmp--);
500 /* Stage 3. Mode Register Set */
501 REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
502 REG8(EMC_SDMR0 | sdmode) = 0;
504 /* Set back to basic DMCR value */
505 REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
507 /* everything is ok now */
510 /* Gets called *before* main */
511 void ICODE_ATTR system_main(void)
513 int i;
515 __dcache_writeback_all();
516 __icache_invalidate_all();
518 write_c0_status(1 << 28 | 1 << 10 ); /* Enable CP | Mask interrupt 2 */
520 /* Disable all interrupts */
521 for(i=0; i<IRQ_MAX; i++)
522 dis_irq(i);
524 mmu_init();
525 pll_init();
526 sdram_init();
528 /* Disable unneeded clocks, clocks are enabled when needed */
529 __cpm_stop_all();
530 __cpm_suspend_usbhost();
532 /* Enable interrupts at core level */
533 enable_interrupt();
536 void system_reboot(void)
538 REG_WDT_TCSR = WDT_TCSR_PRESCALE4 | WDT_TCSR_EXT_EN;
539 REG_WDT_TCNT = 0;
540 REG_WDT_TDR = JZ_EXTAL/1000; /* reset after 4ms */
541 REG_TCU_TSCR = TCU_TSSR_WDTSC; /* enable wdt clock */
542 REG_WDT_TCER = WDT_TCER_TCEN; /* wdt start */
544 while (1);
547 void system_exception_wait(void)
549 /* check for power button without including any .h file */
550 while(1)
552 if( (~REG_GPIO_PXPIN(3)) & (1 << 29) )
553 return;
554 asm volatile("nop");
558 void power_off(void)
560 /* Enable RTC clock */
561 __cpm_start_rtc();
563 /* Put system into hibernate mode */
564 __rtc_clear_alarm_flag();
565 __rtc_clear_hib_stat_all();
566 /* __rtc_set_scratch_pattern(0x12345678); */
567 __rtc_enable_alarm_wakeup();
568 __rtc_set_hrcr_val(0xFE0);
569 __rtc_set_hwfcr_val(0xFFFF << 4);
570 __rtc_power_down();
572 while(1);
575 void system_init(void)
579 int system_memory_guard(int newmode)
581 (void)newmode;
582 return 0;
585 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
586 void set_cpu_frequency(long frequency)
588 unsigned long cfcr = REG_CPM_CPCCR;
589 cfcr &= ~CPM_CPCCR_CDIV_MASK;
591 if(frequency != CPUFREQ_NORMAL)
592 cfcr |= (0 << CPM_CPCCR_CDIV_BIT);
593 else
594 cfcr |= (2 << CPM_CPCCR_CDIV_BIT);
596 REG_CPM_CPCCR = cfcr;
597 cpu_frequency = frequency;
599 #endif