to make u-boot work for fat32 filesystem
[jz_uboot.git] / cpu / mips / jz4750.c
blob2240f5dce281c9d8109c1f7f8a59c62c4d2b81e6
1 /*
2 * Jz4750 common routines
4 * Copyright (c) 2006
5 * Ingenic Semiconductor, <jlwei@ingenic.cn>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
23 #include <config.h>
25 #ifdef CONFIG_JZ4750
27 #include <common.h>
28 #include <command.h>
30 #include <asm/jz4750.h>
32 extern void board_early_init(void);
34 /* PLL output clock = EXTAL * NF / (NR * NO)
36 * NF = FD + 2, NR = RD + 2
37 * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3)
39 void pll_init(void)
41 register unsigned int cfcr, plcr1;
42 int n2FR[33] = {
43 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
44 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
47 int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
48 int nf, pllout2;
50 cfcr = CPM_CPCCR_CLKOEN |
51 CPM_CPCCR_PCS |
52 (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
53 (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
54 (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
55 (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
56 (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
58 pllout2 = (cfcr & CPM_CPCCR_PCS) ? CFG_CPU_SPEED : (CFG_CPU_SPEED / 2);
60 /* Init USB Host clock, pllout2 must be n*48MHz */
61 REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
63 nf = CFG_CPU_SPEED * 2 / CFG_EXTAL;
64 plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
65 (0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
66 (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
67 (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
68 CPM_CPPCR_PLLEN; /* enable PLL */
70 /* init PLL */
71 REG_CPM_CPCCR = cfcr;
72 REG_CPM_CPPCR = plcr1;
75 void pll_add_test(int new_freq)
77 register unsigned int cfcr, plcr1;
78 int n2FR[33] = {
79 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
80 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
83 int div[5] = {1, 4, 4, 4, 4}; /* divisors of I:S:P:M:L */
84 int nf, pllout2;
86 cfcr = CPM_CPCCR_CLKOEN |
87 (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
88 (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
89 (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
90 (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
91 (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
93 pllout2 = (cfcr & CPM_CPCCR_PCS) ? new_freq : (new_freq / 2);
95 /* Init UHC clock */
96 REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
98 //nf = new_freq * 2 / CFG_EXTAL;
99 nf = new_freq / 1000000; //step length is 1M
100 plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
101 (10 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
102 (0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
103 (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
104 CPM_CPPCR_PLLEN; /* enable PLL */
106 /* init PLL */
107 REG_CPM_CPCCR = cfcr;
108 REG_CPM_CPPCR = plcr1;
111 void calc_clocks_add_test(void)
113 DECLARE_GLOBAL_DATA_PTR;
115 #ifndef CONFIG_FPGA
116 unsigned int pllout;
117 unsigned int div[10] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
119 pllout = __cpm_get_pllout();
121 gd->cpu_clk = pllout / div[__cpm_get_cdiv()];
122 gd->sys_clk = pllout / div[__cpm_get_hdiv()];
123 gd->per_clk = pllout / div[__cpm_get_pdiv()];
124 gd->mem_clk = pllout / div[__cpm_get_mdiv()];
125 gd->dev_clk = CFG_EXTAL;
126 #else
127 gd->cpu_clk = gd->sys_clk = gd->per_clk =
128 gd->mem_clk = gd->dev_clk = CFG_EXTAL;
129 #endif
132 void sdram_add_test(int new_freq)
134 register unsigned int dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
136 unsigned int cas_latency_sdmr[2] = {
137 EMC_SDMR_CAS_2,
138 EMC_SDMR_CAS_3,
141 unsigned int cas_latency_dmcr[2] = {
142 1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */
143 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
146 int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
148 cpu_clk = new_freq;
149 mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
151 REG_EMC_RTCSR = EMC_RTCSR_CKS_DISABLE;
152 REG_EMC_RTCOR = 0;
153 REG_EMC_RTCNT = 0;
155 /* Basic DMCR register value. */
156 dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) |
157 ((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) |
158 (SDRAM_BANK4<<EMC_DMCR_BA_BIT) |
159 (SDRAM_BW16<<EMC_DMCR_BW_BIT) |
160 EMC_DMCR_EPIN |
161 cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
163 /* SDRAM timimg parameters */
164 ns = 1000000000 / mem_clk;
166 #if 0
167 tmp = SDRAM_TRAS/ns;
168 if (tmp < 4) tmp = 4;
169 if (tmp > 11) tmp = 11;
170 dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT);
172 tmp = SDRAM_RCD/ns;
173 if (tmp > 3) tmp = 3;
174 dmcr |= (tmp << EMC_DMCR_RCD_BIT);
176 tmp = SDRAM_TPC/ns;
177 if (tmp > 7) tmp = 7;
178 dmcr |= (tmp << EMC_DMCR_TPC_BIT);
180 tmp = SDRAM_TRWL/ns;
181 if (tmp > 3) tmp = 3;
182 dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
184 tmp = (SDRAM_TRAS + SDRAM_TPC)/ns;
185 if (tmp > 14) tmp = 14;
186 dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
187 #else
188 dmcr |= 0xfffc;
189 #endif
191 /* First, precharge phase */
192 REG_EMC_DMCR = dmcr;
194 /* Set refresh registers */
195 tmp = SDRAM_TREF/ns;
196 tmp = tmp/64 + 1;
197 if (tmp > 0xff) tmp = 0xff;
199 REG_EMC_RTCOR = tmp;
200 REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */
202 /* SDRAM mode values */
203 sdmode = EMC_SDMR_BT_SEQ |
204 EMC_SDMR_OM_NORMAL |
205 EMC_SDMR_BL_4 |
206 cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
208 /* precharge all chip-selects */
209 REG8(EMC_SDMR0|sdmode) = 0;
211 /* wait for precharge, > 200us */
212 tmp = (cpu_clk / 1000000) * 200;
213 while (tmp--);
215 /* enable refresh and set SDRAM mode */
216 REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
218 /* write sdram mode register for each chip-select */
219 REG8(EMC_SDMR0|sdmode) = 0;
221 /* everything is ok now */
224 void sdram_init(void)
226 register unsigned int dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
228 #ifdef CONFIG_MOBILE_SDRAM
229 register unsigned int sdemode; /*SDRAM Extended Mode*/
230 #endif
231 unsigned int cas_latency_sdmr[2] = {
232 EMC_SDMR_CAS_2,
233 EMC_SDMR_CAS_3,
236 unsigned int cas_latency_dmcr[2] = {
237 1 << EMC_DMCR_TCL_BIT, /* CAS latency is 2 */
238 2 << EMC_DMCR_TCL_BIT /* CAS latency is 3 */
241 int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
243 cpu_clk = CFG_CPU_SPEED;
244 mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
246 /*set REG_EMC_DMARn for two 64M sdram*/
247 REG_EMC_DMAR0 = EMC_DMAR0_BASE | EMC_DMAR_MASK_64_64;
249 #if CONFIG_NR_DRAM_BANKS == 2 /*Use Two Banks SDRAM*/
250 REG_EMC_DMAR1 = EMC_DMAR1_BASE_64M | EMC_DMAR_MASK_64_64;
251 #endif
253 REG_EMC_BCR = 0; /* Disable bus release */
254 REG_EMC_RTCSR = 0; /* Disable clock for counting */
256 /* Basic DMCR value */
257 dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) |
258 ((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) |
259 (SDRAM_BANK4<<EMC_DMCR_BA_BIT) |
260 (SDRAM_BW16<<EMC_DMCR_BW_BIT) |
261 EMC_DMCR_EPIN |
262 cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
264 /* SDRAM timimg */
265 ns = 1000000000 / mem_clk;
266 tmp = SDRAM_TRAS/ns;
267 if (tmp < 4) tmp = 4;
268 if (tmp > 11) tmp = 11;
269 dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT);
270 tmp = SDRAM_RCD/ns;
271 if (tmp > 3) tmp = 3;
272 dmcr |= (tmp << EMC_DMCR_RCD_BIT);
273 tmp = SDRAM_TPC/ns;
274 if (tmp > 7) tmp = 7;
275 dmcr |= (tmp << EMC_DMCR_TPC_BIT);
276 tmp = SDRAM_TRWL/ns;
277 if (tmp > 3) tmp = 3;
278 dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
279 tmp = (SDRAM_TRAS + SDRAM_TPC)/ns;
280 if (tmp > 14) tmp = 14;
281 dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
283 /* SDRAM mode value */
284 sdmode = EMC_SDMR_BT_SEQ |
285 EMC_SDMR_OM_NORMAL |
286 EMC_SDMR_BL_4 |
287 cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
289 /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
290 REG_EMC_DMCR = dmcr;
291 REG8(EMC_SDMR0|sdmode) = 0;
293 /*Precharge Bank1 SDRAM*/
294 #if CONFIG_NR_DRAM_BANKS == 2
295 REG_EMC_DMCR = dmcr | EMC_DMCR_MBSEL_B1;
296 REG8(EMC_SDMR0|sdmode) = 0;
297 #endif
299 #ifdef CONFIG_MOBILE_SDRAM
300 /* Mobile SDRAM Extended Mode Register */
301 sdemode = EMC_SDMR_SET_BA1 | EMC_SDMR_DS_FULL | EMC_SDMR_PRSR_ALL;
302 #endif
304 /* Wait for precharge, > 200us */
305 tmp = (cpu_clk / 1000000) * 1000;
306 while (tmp--);
308 /* Stage 2. Enable auto-refresh */
309 REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;
311 tmp = SDRAM_TREF/ns;
312 tmp = tmp/64 + 1;
313 if (tmp > 0xff) tmp = 0xff;
314 REG_EMC_RTCOR = tmp;
315 REG_EMC_RTCNT = 0;
316 REG_EMC_RTCSR = EMC_RTCSR_CKS_64; /* Divisor is 64, CKO/64 */
318 /* Wait for number of auto-refresh cycles */
319 tmp = (cpu_clk / 1000000) * 1000;
320 while (tmp--);
322 /* Stage 3. Mode Register Set */
323 REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET | EMC_DMCR_MBSEL_B0;
324 REG8(EMC_SDMR0|sdmode) = 0;
327 #ifdef CONFIG_MOBILE_SDRAM
328 REG8(EMC_SDMR0|sdemode) = 0; /* Set Mobile SDRAM Extended Mode Register */
329 #endif
331 #if CONFIG_NR_DRAM_BANKS == 2
332 REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET | EMC_DMCR_MBSEL_B1;
333 REG8(EMC_SDMR0|sdmode) = 0; /* Set Bank1 SDRAM Register */
336 #ifdef CONFIG_MOBILE_SDRAM
337 REG8(EMC_SDMR0|sdemode) = 0; /* Set Mobile SDRAM Extended Mode Register */
338 #endif
340 #endif /*CONFIG_NR_DRAM_BANKS == 2*/
342 /* Set back to basic DMCR value */
343 REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
345 /* everything is ok now */
348 #ifndef CONFIG_NAND_SPL
350 static void calc_clocks(void)
352 DECLARE_GLOBAL_DATA_PTR;
354 #ifndef CONFIG_FPGA
355 unsigned int pllout;
356 unsigned int div[10] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
358 pllout = __cpm_get_pllout();
360 gd->cpu_clk = pllout / div[__cpm_get_cdiv()];
361 gd->sys_clk = pllout / div[__cpm_get_hdiv()];
362 gd->per_clk = pllout / div[__cpm_get_pdiv()];
363 gd->mem_clk = pllout / div[__cpm_get_mdiv()];
364 gd->dev_clk = CFG_EXTAL;
365 #else
366 gd->cpu_clk = gd->sys_clk = gd->per_clk =
367 gd->mem_clk = gd->dev_clk = CFG_EXTAL;
368 #endif
371 static void rtc_init(void)
374 while ( !__rtc_write_ready()) ;
375 __rtc_enable_alarm(); /* enable alarm */
377 while ( !__rtc_write_ready())
379 REG_RTC_RGR = 0x00007fff; /* type value */
381 while ( !__rtc_write_ready())
383 REG_RTC_HWFCR = 0x0000ffe0; /* Power on delay 2s */
385 while ( !__rtc_write_ready())
387 REG_RTC_HRCR = 0x00000fe0; /* reset delay 125ms */
392 //----------------------------------------------------------------------
393 // jz4750 board init routine
395 int jz_board_init(void)
397 board_early_init(); /* init gpio, pll etc. */
398 #ifndef CONFIG_NAND_U_BOOT
399 #ifndef CONFIG_FPGA
400 pll_init(); /* init PLL */
401 #endif
402 serial_init();
403 sdram_init(); /* init sdram memory */
404 #endif
405 calc_clocks(); /* calc the clocks */
406 #ifndef CONFIG_FPGA
407 rtc_init(); /* init rtc on any reset: */
408 #endif
409 return 0;
412 //----------------------------------------------------------------------
413 // U-Boot common routines
415 long int initdram(int board_type)
417 u32 dmcr;
418 u32 rows, cols, dw, banks;
419 ulong size;
421 dmcr = REG_EMC_DMCR;
422 rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT);
423 cols = 8 + ((dmcr & EMC_DMCR_CA_MASK) >> EMC_DMCR_CA_BIT);
424 dw = (dmcr & EMC_DMCR_BW) ? 2 : 4;
425 banks = (dmcr & EMC_DMCR_BA) ? 4 : 2;
427 size = (1 << (rows + cols)) * dw * banks;
428 size *= CONFIG_NR_DRAM_BANKS;
430 return size;
433 //----------------------------------------------------------------------
434 // Timer routines
436 #define TIMER_CHAN 0
437 #define TIMER_FDATA 0xffff /* Timer full data value */
438 #define TIMER_HZ CFG_HZ
440 #define READ_TIMER REG_TCU_TCNT(TIMER_CHAN) /* macro to read the 16 bit timer */
442 static ulong timestamp;
443 static ulong lastdec;
445 void reset_timer_masked (void);
446 ulong get_timer_masked (void);
447 void udelay_masked (unsigned long usec);
450 * timer without interrupts
453 int timer_init(void)
455 REG_TCU_TCSR(TIMER_CHAN) = TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN;
456 REG_TCU_TCNT(TIMER_CHAN) = 0;
457 REG_TCU_TDHR(TIMER_CHAN) = 0;
458 REG_TCU_TDFR(TIMER_CHAN) = TIMER_FDATA;
460 REG_TCU_TMSR = (1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)); /* mask irqs */
461 REG_TCU_TSCR = (1 << TIMER_CHAN); /* enable timer clock */
462 REG_TCU_TESR = (1 << TIMER_CHAN); /* start counting up */
464 lastdec = 0;
465 timestamp = 0;
467 return 0;
470 void reset_timer(void)
472 reset_timer_masked ();
475 ulong get_timer(ulong base)
477 return get_timer_masked () - base;
480 void set_timer(ulong t)
482 timestamp = t;
485 void udelay (unsigned long usec)
487 ulong tmo,tmp;
489 /* normalize */
490 if (usec >= 1000) {
491 tmo = usec / 1000;
492 tmo *= TIMER_HZ;
493 tmo /= 1000;
495 else {
496 if (usec >= 1) {
497 tmo = usec * TIMER_HZ;
498 tmo /= (1000*1000);
500 else
501 tmo = 1;
504 /* check for rollover during this delay */
505 tmp = get_timer (0);
506 if ((tmp + tmo) < tmp )
507 reset_timer_masked(); /* timer would roll over */
508 else
509 tmo += tmp;
511 while (get_timer_masked () < tmo);
514 void reset_timer_masked (void)
516 /* reset time */
517 lastdec = READ_TIMER;
518 timestamp = 0;
521 ulong get_timer_masked (void)
523 ulong now = READ_TIMER;
525 if (lastdec <= now) {
526 /* normal mode */
527 timestamp += (now - lastdec);
528 } else {
529 /* we have an overflow ... */
530 timestamp += TIMER_FDATA + now - lastdec;
532 lastdec = now;
534 return timestamp;
537 void udelay_masked (unsigned long usec)
539 ulong tmo;
540 ulong endtime;
541 signed long diff;
543 /* normalize */
544 if (usec >= 1000) {
545 tmo = usec / 1000;
546 tmo *= TIMER_HZ;
547 tmo /= 1000;
548 } else {
549 if (usec > 1) {
550 tmo = usec * TIMER_HZ;
551 tmo /= (1000*1000);
552 } else {
553 tmo = 1;
557 endtime = get_timer_masked () + tmo;
559 do {
560 ulong now = get_timer_masked ();
561 diff = endtime - now;
562 } while (diff >= 0);
566 * This function is derived from PowerPC code (read timebase as long long).
567 * On MIPS it just returns the timer value.
569 unsigned long long get_ticks(void)
571 return get_timer(0);
575 * This function is derived from PowerPC code (timebase clock frequency).
576 * On MIPS it returns the number of timer ticks per second.
578 ulong get_tbclk (void)
580 return TIMER_HZ;
583 #endif /* CONFIG_NAND_SPL */
585 //---------------------------------------------------------------------
586 // End of timer routine.
587 //---------------------------------------------------------------------
589 #endif /* CONFIG_JZ4750 */