tizen 2.4 release
[kernel/u-boot-tm1.git] / arch / i386 / cpu / sc520 / sc520.c
1 /*
2  * (C) Copyright 2002
3  * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /* stuff specific for the sc520,
25  * but idependent of implementation */
26
27 #include <common.h>
28 #include <asm/io.h>
29 #include <asm/ic/sc520.h>
30
31 DECLARE_GLOBAL_DATA_PTR;
32
33 /*
34  * utility functions for boards based on the AMD sc520
35  *
36  * void init_sc520(void)
37  * unsigned long init_sc520_dram(void)
38  */
39
40 volatile sc520_mmcr_t *sc520_mmcr = (sc520_mmcr_t *)0xfffef000;
41
42 void init_sc520(void)
43 {
44         /*
45          * Set the UARTxCTL register at it's slower,
46          * baud clock giving us a 1.8432 MHz reference
47          */
48         writeb(0x07, &sc520_mmcr->uart1ctl);
49         writeb(0x07, &sc520_mmcr->uart2ctl);
50
51         /* first set the timer pin mapping */
52         writeb(0x72, &sc520_mmcr->clksel);      /* no clock frequency selected, use 1.1892MHz */
53
54         /* enable PCI bus arbiter (concurrent mode) */
55         writeb(0x02, &sc520_mmcr->sysarbctl);
56
57         /* enable external grants */
58         writeb(0x1f, &sc520_mmcr->sysarbmenb);
59
60         /* enable posted-writes */
61         writeb(0x04, &sc520_mmcr->hbctl);
62
63         if (CONFIG_SYS_SC520_HIGH_SPEED) {
64                 /* set it to 133 MHz and write back */
65                 writeb(0x02, &sc520_mmcr->cpuctl);
66                 gd->cpu_clk = 133000000;
67                 printf("## CPU Speed set to 133MHz\n");
68         } else {
69                 /* set it to 100 MHz and write back */
70                 writeb(0x01, &sc520_mmcr->cpuctl);
71                 printf("## CPU Speed set to 100MHz\n");
72                 gd->cpu_clk = 100000000;
73         }
74
75
76         /* wait at least one millisecond */
77         asm("movl       $0x2000, %%ecx\n"
78             "0:         pushl %%ecx\n"
79             "popl       %%ecx\n"
80             "loop 0b\n": : : "ecx");
81
82         /* turn on the SDRAM write buffer */
83         writeb(0x11, &sc520_mmcr->dbctl);
84
85         /* turn on the cache and disable write through */
86         asm("movl       %%cr0, %%eax\n"
87             "andl       $0x9fffffff, %%eax\n"
88             "movl       %%eax, %%cr0\n"  : : : "eax");
89 }
90
91 unsigned long init_sc520_dram(void)
92 {
93         bd_t *bd = gd->bd;
94
95         u32 dram_present=0;
96         u32 dram_ctrl;
97
98 #ifdef CONFIG_SYS_SDRAM_DRCTMCTL
99         /* these memory control registers are set up in the assember part,
100          * in sc520_asm.S, during 'mem_init'.  If we muck with them here,
101          * after we are running a stack in RAM, we have troubles.  Besides,
102          * these refresh and delay values are better ? simply specified
103          * outright in the include/configs/{cfg} file since the HW designer
104          * simply dictates it.
105          */
106 #else
107         u8 tmp;
108         u8 val;
109
110         int cas_precharge_delay = CONFIG_SYS_SDRAM_PRECHARGE_DELAY;
111         int refresh_rate        = CONFIG_SYS_SDRAM_REFRESH_RATE;
112         int ras_cas_delay       = CONFIG_SYS_SDRAM_RAS_CAS_DELAY;
113
114         /* set SDRAM speed here */
115
116         refresh_rate /= 78;
117         if (refresh_rate <= 1) {
118                 val = 0;        /* 7.8us */
119         } else if (refresh_rate == 2) {
120                 val = 1;        /* 15.6us */
121         } else if (refresh_rate == 3 || refresh_rate == 4) {
122                 val = 2;        /* 31.2us */
123         } else {
124                 val = 3;        /* 62.4us */
125         }
126
127         tmp = (readb(&sc520_mmcr->drcctl) & 0xcf) | (val<<4);
128         writeb(tmp, &sc520_mmcr->drcctl);
129
130         val = readb(&sc520_mmcr->drctmctl) & 0xf0;
131
132         if (cas_precharge_delay==3) {
133                 val |= 0x04;    /* 3T */
134         } else if (cas_precharge_delay==4) {
135                 val |= 0x08;    /* 4T */
136         } else if (cas_precharge_delay>4) {
137                 val |= 0x0c;
138         }
139
140         if (ras_cas_delay > 3) {
141                 val |= 2;
142         } else {
143                 val |= 1;
144         }
145         writeb(val, &c520_mmcr->drctmctl);
146 #endif
147
148         /*
149          * We read-back the configuration of the dram
150          * controller that the assembly code wrote
151          */
152         dram_ctrl = readl(&sc520_mmcr->drcbendadr);
153
154         bd->bi_dram[0].start = 0;
155         if (dram_ctrl & 0x80) {
156                 /* bank 0 enabled */
157                 dram_present = bd->bi_dram[1].start = (dram_ctrl & 0x7f) << 22;
158                 bd->bi_dram[0].size = bd->bi_dram[1].start;
159         } else {
160                 bd->bi_dram[0].size = 0;
161                 bd->bi_dram[1].start = bd->bi_dram[0].start;
162         }
163
164         if (dram_ctrl & 0x8000) {
165                 /* bank 1 enabled */
166                 dram_present = bd->bi_dram[2].start = (dram_ctrl & 0x7f00) << 14;
167                 bd->bi_dram[1].size = bd->bi_dram[2].start -  bd->bi_dram[1].start;
168         } else {
169                 bd->bi_dram[1].size = 0;
170                 bd->bi_dram[2].start = bd->bi_dram[1].start;
171         }
172
173         if (dram_ctrl & 0x800000) {
174                 /* bank 2 enabled */
175                 dram_present = bd->bi_dram[3].start = (dram_ctrl & 0x7f0000) << 6;
176                 bd->bi_dram[2].size = bd->bi_dram[3].start -  bd->bi_dram[2].start;
177         } else {
178                 bd->bi_dram[2].size = 0;
179                 bd->bi_dram[3].start = bd->bi_dram[2].start;
180         }
181
182         if (dram_ctrl & 0x80000000) {
183                 /* bank 3 enabled */
184                 dram_present  = (dram_ctrl & 0x7f000000) >> 2;
185                 bd->bi_dram[3].size = dram_present -  bd->bi_dram[3].start;
186         } else {
187                 bd->bi_dram[3].size = 0;
188         }
189         gd->ram_size = dram_present;
190
191         return dram_present;
192 }
193
194 #ifdef CONFIG_SYS_SC520_RESET
195 void reset_cpu(ulong addr)
196 {
197         printf("Resetting using SC520 MMCR\n");
198         /* Write a '1' to the SYS_RST of the RESCFG MMCR */
199         writeb(0x01, &sc520_mmcr->rescfg);
200
201         /* NOTREACHED */
202 }
203 #endif