[boot] move boot related packages to their own folder
[openwrt.git] / package / boot / uboot-xburst / files / cpu / mips / jz4740.c
1 /*
2  * Jz4740 common routines
3  *
4  *  Copyright (c) 2006
5  *  Ingenic Semiconductor, <jlwei@ingenic.cn>
6  *
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.
11  *
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.
16  *
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
21  */
22
23 #include <config.h>
24
25 #ifdef CONFIG_JZ4740
26 #include <common.h>
27 #include <command.h>
28 #include <asm/jz4740.h>
29
30 extern void board_early_init(void);
31
32 /* PLL output clock = EXTAL * NF / (NR * NO)
33  *
34  * NF = FD + 2, NR = RD + 2
35  * NO = 1 (if OD = 0), NO = 2 (if OD = 1 or 2), NO = 4 (if OD = 3)
36  */
37 void pll_init(void)
38 {
39         register unsigned int cfcr, plcr1;
40         int n2FR[33] = {
41                 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
42                 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
43                 9
44         };
45         int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
46         int nf, pllout2;
47
48         cfcr = CPM_CPCCR_CLKOEN |
49                 CPM_CPCCR_PCS |
50                 (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
51                 (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
52                 (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
53                 (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
54                 (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
55
56         pllout2 = (cfcr & CPM_CPCCR_PCS) ? CONFIG_SYS_CPU_SPEED : (CONFIG_SYS_CPU_SPEED / 2);
57
58         /* Init USB Host clock, pllout2 must be n*48MHz */
59         REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
60
61         nf = CONFIG_SYS_CPU_SPEED * 2 / CONFIG_SYS_EXTAL;
62         plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
63                 (0 << CPM_CPPCR_PLLN_BIT) |     /* RD=0, NR=2 */
64                 (0 << CPM_CPPCR_PLLOD_BIT) |    /* OD=0, NO=1 */
65                 (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
66                 CPM_CPPCR_PLLEN;                /* enable PLL */
67
68         /* init PLL */
69         REG_CPM_CPCCR = cfcr;
70         REG_CPM_CPPCR = plcr1;
71 }
72
73 void pll_add_test(int new_freq)
74 {
75         register unsigned int cfcr, plcr1;
76         int n2FR[33] = {
77                 0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
78                 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
79                 9
80         };
81         int div[5] = {1, 4, 4, 4, 4}; /* divisors of I:S:P:M:L */
82         int nf, pllout2;
83
84         cfcr = CPM_CPCCR_CLKOEN |
85                 (n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
86                 (n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
87                 (n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
88                 (n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
89                 (n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
90
91         pllout2 = (cfcr & CPM_CPCCR_PCS) ? new_freq : (new_freq / 2);
92
93         /* Init UHC clock */
94         REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
95
96         /* nf = new_freq * 2 / CONFIG_SYS_EXTAL; */
97         nf = new_freq / 1000000; /* step length is 1M */
98         plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
99                 (10 << CPM_CPPCR_PLLN_BIT) |    /* RD=0, NR=2 */
100                 (0 << CPM_CPPCR_PLLOD_BIT) |    /* OD=0, NO=1 */
101                 (0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
102                 CPM_CPPCR_PLLEN;                /* enable PLL */
103
104         /* init PLL */
105         REG_CPM_CPCCR = cfcr;
106         REG_CPM_CPPCR = plcr1;
107 }
108
109 void calc_clocks_add_test(void)
110 {
111         DECLARE_GLOBAL_DATA_PTR;
112
113         unsigned int pllout;
114         unsigned int div[10] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
115
116         pllout = __cpm_get_pllout();
117
118         gd->cpu_clk = pllout / div[__cpm_get_cdiv()];
119         gd->sys_clk = pllout / div[__cpm_get_hdiv()];
120         gd->per_clk = pllout / div[__cpm_get_pdiv()];
121         gd->mem_clk = pllout / div[__cpm_get_mdiv()];
122         gd->dev_clk = CONFIG_SYS_EXTAL;
123 }
124
125 void sdram_add_test(int new_freq)
126 {
127         register unsigned int dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
128
129         unsigned int cas_latency_sdmr[2] = {
130                 EMC_SDMR_CAS_2,
131                 EMC_SDMR_CAS_3,
132         };
133
134         unsigned int cas_latency_dmcr[2] = {
135                 1 << EMC_DMCR_TCL_BIT,  /* CAS latency is 2 */
136                 2 << EMC_DMCR_TCL_BIT   /* CAS latency is 3 */
137         };
138
139         int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
140
141         cpu_clk = new_freq;
142         mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
143
144         REG_EMC_RTCSR = EMC_RTCSR_CKS_DISABLE;
145         REG_EMC_RTCOR = 0;
146         REG_EMC_RTCNT = 0;
147
148         /* Basic DMCR register value. */
149         dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) |
150                 ((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) |
151                 (SDRAM_BANK4<<EMC_DMCR_BA_BIT) |
152                 (SDRAM_BW16<<EMC_DMCR_BW_BIT) |
153                 EMC_DMCR_EPIN |
154                 cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
155
156         /* SDRAM timimg parameters */
157         ns = 1000000000 / mem_clk;
158
159 #if 0
160         tmp = SDRAM_TRAS/ns;
161         if (tmp < 4) tmp = 4;
162         if (tmp > 11) tmp = 11;
163         dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT);
164
165         tmp = SDRAM_RCD/ns;
166         if (tmp > 3) tmp = 3;
167         dmcr |= (tmp << EMC_DMCR_RCD_BIT);
168
169         tmp = SDRAM_TPC/ns;
170         if (tmp > 7) tmp = 7;
171         dmcr |= (tmp << EMC_DMCR_TPC_BIT);
172
173         tmp = SDRAM_TRWL/ns;
174         if (tmp > 3) tmp = 3;
175         dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
176
177         tmp = (SDRAM_TRAS + SDRAM_TPC)/ns;
178         if (tmp > 14) tmp = 14;
179         dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
180 #else
181         dmcr |= 0xfffc;
182 #endif
183
184         /* First, precharge phase */
185         REG_EMC_DMCR = dmcr;
186
187         /* Set refresh registers */
188         tmp = SDRAM_TREF/ns;
189         tmp = tmp/64 + 1;
190         if (tmp > 0xff) tmp = 0xff;
191
192         REG_EMC_RTCOR = tmp;
193         REG_EMC_RTCSR = EMC_RTCSR_CKS_64;       /* Divisor is 64, CKO/64 */
194
195         /* SDRAM mode values */
196         sdmode = EMC_SDMR_BT_SEQ | 
197                  EMC_SDMR_OM_NORMAL |
198                  EMC_SDMR_BL_4 | 
199                  cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
200
201         /* precharge all chip-selects */
202         REG8(EMC_SDMR0|sdmode) = 0;
203
204         /* wait for precharge, > 200us */
205         tmp = (cpu_clk / 1000000) * 200;
206         while (tmp--);
207
208         /* enable refresh and set SDRAM mode */
209         REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
210
211         /* write sdram mode register for each chip-select */
212         REG8(EMC_SDMR0|sdmode) = 0;
213
214         /* everything is ok now */
215 }
216
217 void sdram_init(void)
218 {
219         register unsigned int dmcr0, dmcr, sdmode, tmp, cpu_clk, mem_clk, ns;
220
221         unsigned int cas_latency_sdmr[2] = {
222                 EMC_SDMR_CAS_2,
223                 EMC_SDMR_CAS_3,
224         };
225
226         unsigned int cas_latency_dmcr[2] = {
227                 1 << EMC_DMCR_TCL_BIT,  /* CAS latency is 2 */
228                 2 << EMC_DMCR_TCL_BIT   /* CAS latency is 3 */
229         };
230
231         int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
232
233         cpu_clk = CONFIG_SYS_CPU_SPEED;
234         mem_clk = cpu_clk * div[__cpm_get_cdiv()] / div[__cpm_get_mdiv()];
235
236         REG_EMC_BCR = 0;        /* Disable bus release */
237         REG_EMC_RTCSR = 0;      /* Disable clock for counting */
238
239         /* Fault DMCR value for mode register setting*/
240 #define SDRAM_ROW0    11
241 #define SDRAM_COL0     8
242 #define SDRAM_BANK40   0
243
244         dmcr0 = ((SDRAM_ROW0-11)<<EMC_DMCR_RA_BIT) |
245                 ((SDRAM_COL0-8)<<EMC_DMCR_CA_BIT) |
246                 (SDRAM_BANK40<<EMC_DMCR_BA_BIT) |
247                 (SDRAM_BW16<<EMC_DMCR_BW_BIT) |
248                 EMC_DMCR_EPIN |
249                 cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
250
251         /* Basic DMCR value */
252         dmcr = ((SDRAM_ROW-11)<<EMC_DMCR_RA_BIT) |
253                 ((SDRAM_COL-8)<<EMC_DMCR_CA_BIT) |
254                 (SDRAM_BANK4<<EMC_DMCR_BA_BIT) |
255                 (SDRAM_BW16<<EMC_DMCR_BW_BIT) |
256                 EMC_DMCR_EPIN |
257                 cas_latency_dmcr[((SDRAM_CASL == 3) ? 1 : 0)];
258
259         /* SDRAM timimg */
260         ns = 1000000000 / mem_clk;
261         tmp = SDRAM_TRAS/ns;
262         if (tmp < 4) tmp = 4;
263         if (tmp > 11) tmp = 11;
264         dmcr |= ((tmp-4) << EMC_DMCR_TRAS_BIT);
265         tmp = SDRAM_RCD/ns;
266         if (tmp > 3) tmp = 3;
267         dmcr |= (tmp << EMC_DMCR_RCD_BIT);
268         tmp = SDRAM_TPC/ns;
269         if (tmp > 7) tmp = 7;
270         dmcr |= (tmp << EMC_DMCR_TPC_BIT);
271         tmp = SDRAM_TRWL/ns;
272         if (tmp > 3) tmp = 3;
273         dmcr |= (tmp << EMC_DMCR_TRWL_BIT);
274         tmp = (SDRAM_TRAS + SDRAM_TPC)/ns;
275         if (tmp > 14) tmp = 14;
276         dmcr |= (((tmp + 1) >> 1) << EMC_DMCR_TRC_BIT);
277
278         /* SDRAM mode value */
279         sdmode = EMC_SDMR_BT_SEQ | 
280                  EMC_SDMR_OM_NORMAL |
281                  EMC_SDMR_BL_4 | 
282                  cas_latency_sdmr[((SDRAM_CASL == 3) ? 1 : 0)];
283
284         /* Stage 1. Precharge all banks by writing SDMR with DMCR.MRSET=0 */
285         REG_EMC_DMCR = dmcr;
286         REG8(EMC_SDMR0|sdmode) = 0;
287
288         /* Wait for precharge, > 200us */
289         tmp = (cpu_clk / 1000000) * 1000;
290         while (tmp--);
291
292         /* Stage 2. Enable auto-refresh */
293         REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH;
294
295         tmp = SDRAM_TREF/ns;
296         tmp = tmp/64 + 1;
297         if (tmp > 0xff) tmp = 0xff;
298         REG_EMC_RTCOR = tmp;
299         REG_EMC_RTCNT = 0;
300         REG_EMC_RTCSR = EMC_RTCSR_CKS_64;       /* Divisor is 64, CKO/64 */
301
302         /* Wait for number of auto-refresh cycles */
303         tmp = (cpu_clk / 1000000) * 1000;
304         while (tmp--);
305
306         /* Stage 3. Mode Register Set */
307         REG_EMC_DMCR = dmcr0 | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
308         REG8(EMC_SDMR0|sdmode) = 0;
309
310         /* Set back to basic DMCR value */
311         REG_EMC_DMCR = dmcr | EMC_DMCR_RFSH | EMC_DMCR_MRSET;
312
313         /* everything is ok now */
314 }
315
316 #ifndef CONFIG_NAND_SPL
317
318 static void calc_clocks(void)
319 {
320         DECLARE_GLOBAL_DATA_PTR;
321
322         unsigned int pllout;
323         unsigned int div[10] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
324
325         pllout = __cpm_get_pllout();
326
327         gd->cpu_clk = pllout / div[__cpm_get_cdiv()];
328         gd->sys_clk = pllout / div[__cpm_get_hdiv()];
329         gd->per_clk = pllout / div[__cpm_get_pdiv()];
330         gd->mem_clk = pllout / div[__cpm_get_mdiv()];
331         gd->dev_clk = CONFIG_SYS_EXTAL;
332 }
333
334 static void rtc_init(void)
335 {
336         unsigned long rtcsta;
337
338         while ( !__rtc_write_ready()) ;
339         __rtc_enable_alarm();   /* enable alarm */
340
341         while ( !__rtc_write_ready())
342                 ;
343         REG_RTC_RGR   = 0x00007fff; /* type value */
344
345         while ( !__rtc_write_ready())
346                 ;
347         REG_RTC_HWFCR = 0x0000ffe0; /* Power on delay 2s */
348
349         while ( !__rtc_write_ready())
350                 ;
351         REG_RTC_HRCR  = 0x00000fe0; /* reset delay 125ms */
352 #if 0
353         while ( !__rtc_write_ready())
354                 ;
355         rtcsta = REG_RTC_HWRSR;
356         while ( !__rtc_write_ready())
357                 ;
358         if (rtcsta & 0x33) {
359                 if (rtcsta & 0x10) {
360                         while ( !__rtc_write_ready())
361                                 ;
362                         REG_RTC_RSR = 0x0;
363                 }
364                 while ( !__rtc_write_ready())
365                         ;
366                 REG_RTC_HWRSR = 0x0;
367         }
368 #endif
369 }
370
371 /*
372  * jz4740 board init routine
373  */
374 int jz_board_init(void)
375 {
376         board_early_init();  /* init gpio, pll etc. */
377 #ifndef CONFIG_NAND_U_BOOT
378         pll_init();          /* init PLL */
379         sdram_init();        /* init sdram memory */
380 #endif
381         calc_clocks();       /* calc the clocks */
382         rtc_init();             /* init rtc on any reset: */
383         return 0;
384 }
385
386 /* U-Boot common routines */
387 phys_size_t initdram(int board_type)
388 {
389         u32 dmcr;
390         u32 rows, cols, dw, banks;
391         ulong size;
392
393         dmcr = REG_EMC_DMCR;
394         rows = 11 + ((dmcr & EMC_DMCR_RA_MASK) >> EMC_DMCR_RA_BIT);
395         cols = 8 + ((dmcr & EMC_DMCR_CA_MASK) >> EMC_DMCR_CA_BIT);
396         dw = (dmcr & EMC_DMCR_BW) ? 2 : 4;
397         banks = (dmcr & EMC_DMCR_BA) ? 4 : 2;
398
399         size = (1 << (rows + cols)) * dw * banks;
400
401         return size;
402 }
403
404 /*
405  * Timer routines 
406  */
407
408 #define TIMER_CHAN  0
409 #define TIMER_FDATA 0xffff  /* Timer full data value */
410 #define TIMER_HZ    CONFIG_SYS_HZ
411
412 #define READ_TIMER  REG_TCU_TCNT(TIMER_CHAN)  /* macro to read the 16 bit timer */
413
414 static ulong timestamp;
415 static ulong lastdec;
416
417 void    reset_timer_masked      (void);
418 ulong   get_timer_masked        (void);
419 void    udelay_masked           (unsigned long usec);
420
421 /*
422  * timer without interrupts
423  */
424
425 int timer_init(void)
426 {
427         REG_TCU_TCSR(TIMER_CHAN) = TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN;
428         REG_TCU_TCNT(TIMER_CHAN) = 0;
429         REG_TCU_TDHR(TIMER_CHAN) = 0;
430         REG_TCU_TDFR(TIMER_CHAN) = TIMER_FDATA;
431
432         REG_TCU_TMSR = (1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)); /* mask irqs */
433         REG_TCU_TSCR = (1 << TIMER_CHAN); /* enable timer clock */
434         REG_TCU_TESR = (1 << TIMER_CHAN); /* start counting up */
435
436         lastdec = 0;
437         timestamp = 0;
438
439         return 0;
440 }
441
442 void reset_timer(void)
443 {
444         reset_timer_masked ();
445 }
446
447 ulong get_timer(ulong base)
448 {
449         return get_timer_masked () - base;
450 }
451
452 void set_timer(ulong t)
453 {
454         timestamp = t;
455 }
456
457 void udelay (unsigned long usec)
458 {
459         ulong tmo,tmp;
460
461         /* normalize */
462         if (usec >= 1000) {
463                 tmo = usec / 1000;
464                 tmo *= TIMER_HZ;
465                 tmo /= 1000;
466         }
467         else {
468                 if (usec >= 1) {
469                         tmo = usec * TIMER_HZ;
470                         tmo /= (1000*1000);
471                 }
472                 else
473                         tmo = 1;
474         }
475
476         /* check for rollover during this delay */
477         tmp = get_timer (0);
478         if ((tmp + tmo) < tmp )
479                 reset_timer_masked();  /* timer would roll over */
480         else
481                 tmo += tmp;
482
483         while (get_timer_masked () < tmo);
484 }
485
486 void reset_timer_masked (void)
487 {
488         /* reset time */
489         lastdec = READ_TIMER;
490         timestamp = 0;
491 }
492
493 ulong get_timer_masked (void)
494 {
495         ulong now = READ_TIMER;
496
497         if (lastdec <= now) {
498                 /* normal mode */
499                 timestamp += (now - lastdec);
500         } else {
501                 /* we have an overflow ... */
502                 timestamp += TIMER_FDATA + now - lastdec;
503         }
504         lastdec = now;
505
506         return timestamp;
507 }
508
509 void udelay_masked (unsigned long usec)
510 {
511         ulong tmo;
512         ulong endtime;
513         signed long diff;
514
515         /* normalize */
516         if (usec >= 1000) {
517                 tmo = usec / 1000;
518                 tmo *= TIMER_HZ;
519                 tmo /= 1000;
520         } else {
521                 if (usec > 1) {
522                         tmo = usec * TIMER_HZ;
523                         tmo /= (1000*1000);
524                 } else {
525                         tmo = 1;
526                 }
527         }
528
529         endtime = get_timer_masked () + tmo;
530
531         do {
532                 ulong now = get_timer_masked ();
533                 diff = endtime - now;
534         } while (diff >= 0);
535 }
536
537 /*
538  * This function is derived from PowerPC code (read timebase as long long).
539  * On MIPS it just returns the timer value.
540  */
541 unsigned long long get_ticks(void)
542 {
543         return get_timer(0);
544 }
545
546 /*
547  * This function is derived from PowerPC code (timebase clock frequency).
548  * On MIPS it returns the number of timer ticks per second.
549  */
550 ulong get_tbclk (void)
551 {
552         return TIMER_HZ;
553 }
554
555 #endif /* CONFIG_NAND_SPL */
556
557 /* End of timer routine. */
558
559 #endif