sc520: Move board specific settings to board init function
[platform/kernel/u-boot.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/processor-flags.h>
30 #include <asm/ic/sc520.h>
31
32 DECLARE_GLOBAL_DATA_PTR;
33
34 /*
35  * utility functions for boards based on the AMD sc520
36  *
37  * void init_sc520(void)
38  * unsigned long init_sc520_dram(void)
39  */
40
41 sc520_mmcr_t *sc520_mmcr = (sc520_mmcr_t *)SC520_MMCR_BASE;
42
43 int cpu_init_f(void)
44 {
45         if (CONFIG_SYS_SC520_HIGH_SPEED) {
46                 /* set it to 133 MHz and write back */
47                 writeb(0x02, &sc520_mmcr->cpuctl);
48                 gd->cpu_clk = 133000000;
49                 printf("## CPU Speed set to 133MHz\n");
50         } else {
51                 /* set it to 100 MHz and write back */
52                 writeb(0x01, &sc520_mmcr->cpuctl);
53                 printf("## CPU Speed set to 100MHz\n");
54                 gd->cpu_clk = 100000000;
55         }
56
57
58         /* wait at least one millisecond */
59         asm("movl       $0x2000, %%ecx\n"
60             "0:         pushl %%ecx\n"
61             "popl       %%ecx\n"
62             "loop 0b\n": : : "ecx");
63
64         /* turn on the SDRAM write buffer */
65         writeb(0x11, &sc520_mmcr->dbctl);
66
67         return x86_cpu_init_f();
68 }
69
70 unsigned long init_sc520_dram(void)
71 {
72         bd_t *bd = gd->bd;
73
74         u32 dram_present=0;
75         u32 dram_ctrl;
76
77 #ifdef CONFIG_SYS_SDRAM_DRCTMCTL
78         /* these memory control registers are set up in the assember part,
79          * in sc520_asm.S, during 'mem_init'.  If we muck with them here,
80          * after we are running a stack in RAM, we have troubles.  Besides,
81          * these refresh and delay values are better ? simply specified
82          * outright in the include/configs/{cfg} file since the HW designer
83          * simply dictates it.
84          */
85 #else
86         u8 tmp;
87         u8 val;
88
89         int cas_precharge_delay = CONFIG_SYS_SDRAM_PRECHARGE_DELAY;
90         int refresh_rate        = CONFIG_SYS_SDRAM_REFRESH_RATE;
91         int ras_cas_delay       = CONFIG_SYS_SDRAM_RAS_CAS_DELAY;
92
93         /* set SDRAM speed here */
94
95         refresh_rate /= 78;
96         if (refresh_rate <= 1) {
97                 val = 0;        /* 7.8us */
98         } else if (refresh_rate == 2) {
99                 val = 1;        /* 15.6us */
100         } else if (refresh_rate == 3 || refresh_rate == 4) {
101                 val = 2;        /* 31.2us */
102         } else {
103                 val = 3;        /* 62.4us */
104         }
105
106         tmp = (readb(&sc520_mmcr->drcctl) & 0xcf) | (val<<4);
107         writeb(tmp, &sc520_mmcr->drcctl);
108
109         val = readb(&sc520_mmcr->drctmctl) & 0xf0;
110
111         if (cas_precharge_delay==3) {
112                 val |= 0x04;    /* 3T */
113         } else if (cas_precharge_delay==4) {
114                 val |= 0x08;    /* 4T */
115         } else if (cas_precharge_delay>4) {
116                 val |= 0x0c;
117         }
118
119         if (ras_cas_delay > 3) {
120                 val |= 2;
121         } else {
122                 val |= 1;
123         }
124         writeb(val, &c520_mmcr->drctmctl);
125 #endif
126
127         /*
128          * We read-back the configuration of the dram
129          * controller that the assembly code wrote
130          */
131         dram_ctrl = readl(&sc520_mmcr->drcbendadr);
132
133         bd->bi_dram[0].start = 0;
134         if (dram_ctrl & 0x80) {
135                 /* bank 0 enabled */
136                 dram_present = bd->bi_dram[1].start = (dram_ctrl & 0x7f) << 22;
137                 bd->bi_dram[0].size = bd->bi_dram[1].start;
138         } else {
139                 bd->bi_dram[0].size = 0;
140                 bd->bi_dram[1].start = bd->bi_dram[0].start;
141         }
142
143         if (dram_ctrl & 0x8000) {
144                 /* bank 1 enabled */
145                 dram_present = bd->bi_dram[2].start = (dram_ctrl & 0x7f00) << 14;
146                 bd->bi_dram[1].size = bd->bi_dram[2].start -  bd->bi_dram[1].start;
147         } else {
148                 bd->bi_dram[1].size = 0;
149                 bd->bi_dram[2].start = bd->bi_dram[1].start;
150         }
151
152         if (dram_ctrl & 0x800000) {
153                 /* bank 2 enabled */
154                 dram_present = bd->bi_dram[3].start = (dram_ctrl & 0x7f0000) << 6;
155                 bd->bi_dram[2].size = bd->bi_dram[3].start -  bd->bi_dram[2].start;
156         } else {
157                 bd->bi_dram[2].size = 0;
158                 bd->bi_dram[3].start = bd->bi_dram[2].start;
159         }
160
161         if (dram_ctrl & 0x80000000) {
162                 /* bank 3 enabled */
163                 dram_present  = (dram_ctrl & 0x7f000000) >> 2;
164                 bd->bi_dram[3].size = dram_present -  bd->bi_dram[3].start;
165         } else {
166                 bd->bi_dram[3].size = 0;
167         }
168         gd->ram_size = dram_present;
169
170         return dram_present;
171 }
172
173 #ifdef CONFIG_SYS_SC520_RESET
174 void reset_cpu(ulong addr)
175 {
176         printf("Resetting using SC520 MMCR\n");
177         /* Write a '1' to the SYS_RST of the RESCFG MMCR */
178         writeb(0x01, &sc520_mmcr->rescfg);
179
180         /* NOTREACHED */
181 }
182 #endif