2 * Jz4750 common routines
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,
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)
41 register unsigned int cfcr
, plcr1
;
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 */
50 cfcr
= CPM_CPCCR_CLKOEN
|
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 */
72 REG_CPM_CPPCR
= plcr1
;
75 void pll_add_test(int new_freq
)
77 register unsigned int cfcr
, plcr1
;
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 */
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);
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 */
107 REG_CPM_CPCCR
= cfcr
;
108 REG_CPM_CPPCR
= plcr1
;
111 void calc_clocks_add_test(void)
113 DECLARE_GLOBAL_DATA_PTR
;
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
;
127 gd
->cpu_clk
= gd
->sys_clk
= gd
->per_clk
=
128 gd
->mem_clk
= gd
->dev_clk
= CFG_EXTAL
;
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] = {
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};
149 mem_clk
= cpu_clk
* div
[__cpm_get_cdiv()] / div
[__cpm_get_mdiv()];
151 REG_EMC_RTCSR
= EMC_RTCSR_CKS_DISABLE
;
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
) |
161 cas_latency_dmcr
[((SDRAM_CASL
== 3) ? 1 : 0)];
163 /* SDRAM timimg parameters */
164 ns
= 1000000000 / mem_clk
;
168 if (tmp
< 4) tmp
= 4;
169 if (tmp
> 11) tmp
= 11;
170 dmcr
|= ((tmp
-4) << EMC_DMCR_TRAS_BIT
);
173 if (tmp
> 3) tmp
= 3;
174 dmcr
|= (tmp
<< EMC_DMCR_RCD_BIT
);
177 if (tmp
> 7) tmp
= 7;
178 dmcr
|= (tmp
<< EMC_DMCR_TPC_BIT
);
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
);
191 /* First, precharge phase */
194 /* Set refresh registers */
197 if (tmp
> 0xff) tmp
= 0xff;
200 REG_EMC_RTCSR
= EMC_RTCSR_CKS_64
; /* Divisor is 64, CKO/64 */
202 /* SDRAM mode values */
203 sdmode
= EMC_SDMR_BT_SEQ
|
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;
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*/
231 unsigned int cas_latency_sdmr
[2] = {
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
;
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
) |
262 cas_latency_dmcr
[((SDRAM_CASL
== 3) ? 1 : 0)];
265 ns
= 1000000000 / mem_clk
;
267 if (tmp
< 4) tmp
= 4;
268 if (tmp
> 11) tmp
= 11;
269 dmcr
|= ((tmp
-4) << EMC_DMCR_TRAS_BIT
);
271 if (tmp
> 3) tmp
= 3;
272 dmcr
|= (tmp
<< EMC_DMCR_RCD_BIT
);
274 if (tmp
> 7) tmp
= 7;
275 dmcr
|= (tmp
<< EMC_DMCR_TPC_BIT
);
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
|
287 cas_latency_sdmr
[((SDRAM_CASL
== 3) ? 1 : 0)];
289 /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
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;
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
;
304 /* Wait for precharge, > 200us */
305 tmp
= (cpu_clk
/ 1000000) * 1000;
308 /* Stage 2. Enable auto-refresh */
309 REG_EMC_DMCR
= dmcr
| EMC_DMCR_RFSH
;
313 if (tmp
> 0xff) tmp
= 0xff;
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;
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 */
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 */
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
;
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
;
366 gd
->cpu_clk
= gd
->sys_clk
= gd
->per_clk
=
367 gd
->mem_clk
= gd
->dev_clk
= CFG_EXTAL
;
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
400 pll_init(); /* init PLL */
403 sdram_init(); /* init sdram memory */
405 calc_clocks(); /* calc the clocks */
407 rtc_init(); /* init rtc on any reset: */
412 //----------------------------------------------------------------------
413 // U-Boot common routines
415 long int initdram(int board_type
)
418 u32 rows
, cols
, dw
, banks
;
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
;
433 //----------------------------------------------------------------------
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
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 */
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
)
485 void udelay (unsigned long usec
)
497 tmo
= usec
* TIMER_HZ
;
504 /* check for rollover during this delay */
506 if ((tmp
+ tmo
) < tmp
)
507 reset_timer_masked(); /* timer would roll over */
511 while (get_timer_masked () < tmo
);
514 void reset_timer_masked (void)
517 lastdec
= READ_TIMER
;
521 ulong
get_timer_masked (void)
523 ulong now
= READ_TIMER
;
525 if (lastdec
<= now
) {
527 timestamp
+= (now
- lastdec
);
529 /* we have an overflow ... */
530 timestamp
+= TIMER_FDATA
+ now
- lastdec
;
537 void udelay_masked (unsigned long usec
)
550 tmo
= usec
* TIMER_HZ
;
557 endtime
= get_timer_masked () + tmo
;
560 ulong now
= get_timer_masked ();
561 diff
= endtime
- now
;
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)
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)
583 #endif /* CONFIG_NAND_SPL */
585 //---------------------------------------------------------------------
586 // End of timer routine.
587 //---------------------------------------------------------------------
589 #endif /* CONFIG_JZ4750 */