x86: Add processor flags header from linux
[oweals/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 volatile sc520_mmcr_t *sc520_mmcr = (sc520_mmcr_t *)0xfffef000;
42
43 void init_sc520(void)
44 {
45         const u32 nw_cd_rst = ~(X86_CR0_NW | X86_CR0_CD);
46
47         /*
48          * Set the UARTxCTL register at it's slower,
49          * baud clock giving us a 1.8432 MHz reference
50          */
51         writeb(0x07, &sc520_mmcr->uart1ctl);
52         writeb(0x07, &sc520_mmcr->uart2ctl);
53
54         /* first set the timer pin mapping */
55         writeb(0x72, &sc520_mmcr->clksel);      /* no clock frequency selected, use 1.1892MHz */
56
57         /* enable PCI bus arbiter (concurrent mode) */
58         writeb(0x02, &sc520_mmcr->sysarbctl);
59
60         /* enable external grants */
61         writeb(0x1f, &sc520_mmcr->sysarbmenb);
62
63         /* enable posted-writes */
64         writeb(0x04, &sc520_mmcr->hbctl);
65
66         if (CONFIG_SYS_SC520_HIGH_SPEED) {
67                 /* set it to 133 MHz and write back */
68                 writeb(0x02, &sc520_mmcr->cpuctl);
69                 gd->cpu_clk = 133000000;
70                 printf("## CPU Speed set to 133MHz\n");
71         } else {
72                 /* set it to 100 MHz and write back */
73                 writeb(0x01, &sc520_mmcr->cpuctl);
74                 printf("## CPU Speed set to 100MHz\n");
75                 gd->cpu_clk = 100000000;
76         }
77
78
79         /* wait at least one millisecond */
80         asm("movl       $0x2000, %%ecx\n"
81             "0:         pushl %%ecx\n"
82             "popl       %%ecx\n"
83             "loop 0b\n": : : "ecx");
84
85         /* turn on the SDRAM write buffer */
86         writeb(0x11, &sc520_mmcr->dbctl);
87
88         /* turn on the cache and disable write through */
89         asm("movl       %%cr0, %%eax\n"
90             "andl       %0, %%eax\n"
91             "movl       %%eax, %%cr0\n"  : : "i" (nw_cd_rst) : "eax");
92 }
93
94 unsigned long init_sc520_dram(void)
95 {
96         bd_t *bd = gd->bd;
97
98         u32 dram_present=0;
99         u32 dram_ctrl;
100
101 #ifdef CONFIG_SYS_SDRAM_DRCTMCTL
102         /* these memory control registers are set up in the assember part,
103          * in sc520_asm.S, during 'mem_init'.  If we muck with them here,
104          * after we are running a stack in RAM, we have troubles.  Besides,
105          * these refresh and delay values are better ? simply specified
106          * outright in the include/configs/{cfg} file since the HW designer
107          * simply dictates it.
108          */
109 #else
110         u8 tmp;
111         u8 val;
112
113         int cas_precharge_delay = CONFIG_SYS_SDRAM_PRECHARGE_DELAY;
114         int refresh_rate        = CONFIG_SYS_SDRAM_REFRESH_RATE;
115         int ras_cas_delay       = CONFIG_SYS_SDRAM_RAS_CAS_DELAY;
116
117         /* set SDRAM speed here */
118
119         refresh_rate /= 78;
120         if (refresh_rate <= 1) {
121                 val = 0;        /* 7.8us */
122         } else if (refresh_rate == 2) {
123                 val = 1;        /* 15.6us */
124         } else if (refresh_rate == 3 || refresh_rate == 4) {
125                 val = 2;        /* 31.2us */
126         } else {
127                 val = 3;        /* 62.4us */
128         }
129
130         tmp = (readb(&sc520_mmcr->drcctl) & 0xcf) | (val<<4);
131         writeb(tmp, &sc520_mmcr->drcctl);
132
133         val = readb(&sc520_mmcr->drctmctl) & 0xf0;
134
135         if (cas_precharge_delay==3) {
136                 val |= 0x04;    /* 3T */
137         } else if (cas_precharge_delay==4) {
138                 val |= 0x08;    /* 4T */
139         } else if (cas_precharge_delay>4) {
140                 val |= 0x0c;
141         }
142
143         if (ras_cas_delay > 3) {
144                 val |= 2;
145         } else {
146                 val |= 1;
147         }
148         writeb(val, &c520_mmcr->drctmctl);
149 #endif
150
151         /*
152          * We read-back the configuration of the dram
153          * controller that the assembly code wrote
154          */
155         dram_ctrl = readl(&sc520_mmcr->drcbendadr);
156
157         bd->bi_dram[0].start = 0;
158         if (dram_ctrl & 0x80) {
159                 /* bank 0 enabled */
160                 dram_present = bd->bi_dram[1].start = (dram_ctrl & 0x7f) << 22;
161                 bd->bi_dram[0].size = bd->bi_dram[1].start;
162         } else {
163                 bd->bi_dram[0].size = 0;
164                 bd->bi_dram[1].start = bd->bi_dram[0].start;
165         }
166
167         if (dram_ctrl & 0x8000) {
168                 /* bank 1 enabled */
169                 dram_present = bd->bi_dram[2].start = (dram_ctrl & 0x7f00) << 14;
170                 bd->bi_dram[1].size = bd->bi_dram[2].start -  bd->bi_dram[1].start;
171         } else {
172                 bd->bi_dram[1].size = 0;
173                 bd->bi_dram[2].start = bd->bi_dram[1].start;
174         }
175
176         if (dram_ctrl & 0x800000) {
177                 /* bank 2 enabled */
178                 dram_present = bd->bi_dram[3].start = (dram_ctrl & 0x7f0000) << 6;
179                 bd->bi_dram[2].size = bd->bi_dram[3].start -  bd->bi_dram[2].start;
180         } else {
181                 bd->bi_dram[2].size = 0;
182                 bd->bi_dram[3].start = bd->bi_dram[2].start;
183         }
184
185         if (dram_ctrl & 0x80000000) {
186                 /* bank 3 enabled */
187                 dram_present  = (dram_ctrl & 0x7f000000) >> 2;
188                 bd->bi_dram[3].size = dram_present -  bd->bi_dram[3].start;
189         } else {
190                 bd->bi_dram[3].size = 0;
191         }
192         gd->ram_size = dram_present;
193
194         return dram_present;
195 }
196
197 #ifdef CONFIG_SYS_SC520_RESET
198 void reset_cpu(ulong addr)
199 {
200         printf("Resetting using SC520 MMCR\n");
201         /* Write a '1' to the SYS_RST of the RESCFG MMCR */
202         writeb(0x01, &sc520_mmcr->rescfg);
203
204         /* NOTREACHED */
205 }
206 #endif