OMAP3: Print correct silicon revision
[oweals/u-boot.git] / cpu / i386 / 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 write_mmcr_byte(u16 mmcr, u8 data)
37  * void write_mmcr_word(u16 mmcr, u16 data)
38  * void write_mmcr_long(u16 mmcr, u32 data)
39  *
40  * u8   read_mmcr_byte(u16 mmcr)
41  * u16  read_mmcr_word(u16 mmcr)
42  * u32  read_mmcr_long(u16 mmcr)
43  *
44  * void init_sc520(void)
45  * unsigned long init_sc520_dram(void)
46  */
47
48 static u32 mmcr_base= 0xfffef000;
49
50 void write_mmcr_byte(u16 mmcr, u8 data)
51 {
52         writeb(data, mmcr+mmcr_base);
53 }
54
55 void write_mmcr_word(u16 mmcr, u16 data)
56 {
57         writew(data, mmcr+mmcr_base);
58 }
59
60 void write_mmcr_long(u16 mmcr, u32 data)
61 {
62         writel(data, mmcr+mmcr_base);
63 }
64
65 u8 read_mmcr_byte(u16 mmcr)
66 {
67         return readb(mmcr+mmcr_base);
68 }
69
70 u16 read_mmcr_word(u16 mmcr)
71 {
72         return readw(mmcr+mmcr_base);
73 }
74
75 u32 read_mmcr_long(u16 mmcr)
76 {
77         return readl(mmcr+mmcr_base);
78 }
79
80
81 void init_sc520(void)
82 {
83         /* Set the UARTxCTL register at it's slower,
84          * baud clock giving us a 1.8432 MHz reference
85          */
86         write_mmcr_byte(SC520_UART1CTL, 7);
87         write_mmcr_byte(SC520_UART2CTL, 7);
88
89         /* first set the timer pin mapping */
90         write_mmcr_byte(SC520_CLKSEL, 0x72);    /* no clock frequency selected, use 1.1892MHz */
91
92         /* enable PCI bus arbitrer */
93         write_mmcr_byte(SC520_SYSARBCTL,0x02);  /* enable concurrent mode */
94
95         write_mmcr_word(SC520_SYSARBMENB,0x1f); /* enable external grants */
96         write_mmcr_word(SC520_HBCTL,0x04);      /* enable posted-writes */
97
98
99         if (CONFIG_SYS_SC520_HIGH_SPEED) {
100                 write_mmcr_byte(SC520_CPUCTL, 0x2);     /* set it to 133 MHz and write back */
101                 gd->cpu_clk = 133000000;
102                 printf("## CPU Speed set to 133MHz\n");
103         } else {
104                 write_mmcr_byte(SC520_CPUCTL, 1);       /* set CPU to 100 MHz and write back cache */
105                 printf("## CPU Speed set to 100MHz\n");
106                 gd->cpu_clk = 100000000;
107         }
108
109
110         /* wait at least one millisecond */
111         asm("movl       $0x2000,%%ecx\n"
112             "wait_loop: pushl %%ecx\n"
113             "popl       %%ecx\n"
114             "loop wait_loop\n": : : "ecx");
115
116         /* turn on the SDRAM write buffer */
117         write_mmcr_byte(SC520_DBCTL, 0x11);
118
119         /* turn on the cache and disable write through */
120         asm("movl       %%cr0, %%eax\n"
121             "andl       $0x9fffffff, %%eax\n"
122             "movl       %%eax, %%cr0\n"  : : : "eax");
123 }
124
125 unsigned long init_sc520_dram(void)
126 {
127         bd_t *bd = gd->bd;
128
129         u32 dram_present=0;
130         u32 dram_ctrl;
131 #ifdef CONFIG_SYS_SDRAM_DRCTMCTL
132         /* these memory control registers are set up in the assember part,
133          * in sc520_asm.S, during 'mem_init'.  If we muck with them here,
134          * after we are running a stack in RAM, we have troubles.  Besides,
135          * these refresh and delay values are better ? simply specified
136          * outright in the include/configs/{cfg} file since the HW designer
137          * simply dictates it.
138          */
139 #else
140         int val;
141
142         int cas_precharge_delay = CONFIG_SYS_SDRAM_PRECHARGE_DELAY;
143         int refresh_rate        = CONFIG_SYS_SDRAM_REFRESH_RATE;
144         int ras_cas_delay       = CONFIG_SYS_SDRAM_RAS_CAS_DELAY;
145
146         /* set SDRAM speed here */
147
148         refresh_rate/=78;
149         if (refresh_rate<=1) {
150                 val = 0;  /* 7.8us */
151         } else if (refresh_rate==2) {
152                 val = 1;  /* 15.6us */
153         } else if (refresh_rate==3 || refresh_rate==4) {
154                 val = 2;  /* 31.2us */
155         } else {
156                 val = 3;  /* 62.4us */
157         }
158
159         write_mmcr_byte(SC520_DRCCTL, (read_mmcr_byte(SC520_DRCCTL) & 0xcf) | (val<<4));
160
161         val = read_mmcr_byte(SC520_DRCTMCTL);
162         val &= 0xf0;
163
164         if (cas_precharge_delay==3) {
165                 val |= 0x04;   /* 3T */
166         } else if (cas_precharge_delay==4) {
167                 val |= 0x08;   /* 4T */
168         } else if (cas_precharge_delay>4) {
169                 val |= 0x0c;
170         }
171
172         if (ras_cas_delay > 3) {
173                 val |= 2;
174         } else {
175                 val |= 1;
176         }
177         write_mmcr_byte(SC520_DRCTMCTL, val);
178 #endif
179
180         /* We read-back the configuration of the dram
181          * controller that the assembly code wrote */
182         dram_ctrl = read_mmcr_long(SC520_DRCBENDADR);
183
184         bd->bi_dram[0].start = 0;
185         if (dram_ctrl & 0x80) {
186                 /* bank 0 enabled */
187                 dram_present = bd->bi_dram[1].start = (dram_ctrl & 0x7f) << 22;
188                 bd->bi_dram[0].size = bd->bi_dram[1].start;
189
190         } else {
191                 bd->bi_dram[0].size = 0;
192                 bd->bi_dram[1].start = bd->bi_dram[0].start;
193         }
194
195         if (dram_ctrl & 0x8000) {
196                 /* bank 1 enabled */
197                 dram_present = bd->bi_dram[2].start = (dram_ctrl & 0x7f00) << 14;
198                 bd->bi_dram[1].size = bd->bi_dram[2].start -  bd->bi_dram[1].start;
199         } else {
200                 bd->bi_dram[1].size = 0;
201                 bd->bi_dram[2].start = bd->bi_dram[1].start;
202         }
203
204         if (dram_ctrl & 0x800000) {
205                 /* bank 2 enabled */
206                 dram_present = bd->bi_dram[3].start = (dram_ctrl & 0x7f0000) << 6;
207                 bd->bi_dram[2].size = bd->bi_dram[3].start -  bd->bi_dram[2].start;
208         } else {
209                 bd->bi_dram[2].size = 0;
210                 bd->bi_dram[3].start = bd->bi_dram[2].start;
211         }
212
213         if (dram_ctrl & 0x80000000) {
214                 /* bank 3 enabled */
215                 dram_present  = (dram_ctrl & 0x7f000000) >> 2;
216                 bd->bi_dram[3].size = dram_present -  bd->bi_dram[3].start;
217         } else {
218                 bd->bi_dram[3].size = 0;
219         }
220
221
222 #if 0
223         printf("Configured %d bytes of dram\n", dram_present);
224 #endif
225         gd->ram_size = dram_present;
226
227         return dram_present;
228 }
229
230 #ifdef CONFIG_SYS_SC520_RESET
231 void reset_cpu(ulong addr)
232 {
233         printf("Resetting using SC520 MMCR\n");
234         /* Write a '1' to the SYS_RST of the RESCFG MMCR */
235         write_mmcr_word(SC520_RESCFG, 0x0001);
236
237         /* NOTREACHED */
238 }
239 #endif