aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc/syslib/mpc52xx_setup.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/ppc/syslib/mpc52xx_setup.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/ppc/syslib/mpc52xx_setup.c')
-rw-r--r--arch/ppc/syslib/mpc52xx_setup.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
new file mode 100644
index 000000000000..bb2374585a7b
--- /dev/null
+++ b/arch/ppc/syslib/mpc52xx_setup.c
@@ -0,0 +1,230 @@
1/*
2 * arch/ppc/syslib/mpc52xx_setup.c
3 *
4 * Common code for the boards based on Freescale MPC52xx embedded CPU.
5 *
6 *
7 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
8 *
9 * Support for other bootloaders than UBoot by Dale Farnsworth
10 * <dfarnsworth@mvista.com>
11 *
12 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
13 * Copyright (C) 2003 Montavista Software, Inc
14 *
15 * This file is licensed under the terms of the GNU General Public License
16 * version 2. This program is licensed "as is" without any warranty of any
17 * kind, whether express or implied.
18 */
19
20#include <linux/config.h>
21
22#include <asm/io.h>
23#include <asm/time.h>
24#include <asm/mpc52xx.h>
25#include <asm/mpc52xx_psc.h>
26#include <asm/pgtable.h>
27#include <asm/ppcboot.h>
28
29extern bd_t __res;
30
31static int core_mult[] = { /* CPU Frequency multiplier, taken */
32 0, 0, 0, 10, 20, 20, 25, 45, /* from the datasheet used to compute */
33 30, 55, 40, 50, 0, 60, 35, 0, /* CPU frequency from XLB freq and */
34 30, 25, 65, 10, 70, 20, 75, 45, /* external jumper config */
35 0, 55, 40, 50, 80, 60, 35, 0
36};
37
38void
39mpc52xx_restart(char *cmd)
40{
41 struct mpc52xx_gpt __iomem *gpt0 = MPC52xx_VA(MPC52xx_GPTx_OFFSET(0));
42
43 local_irq_disable();
44
45 /* Turn on the watchdog and wait for it to expire. It effectively
46 does a reset */
47 out_be32(&gpt0->count, 0x000000ff);
48 out_be32(&gpt0->mode, 0x00009004);
49
50 while (1);
51}
52
53void
54mpc52xx_halt(void)
55{
56 local_irq_disable();
57
58 while (1);
59}
60
61void
62mpc52xx_power_off(void)
63{
64 /* By default we don't have any way of shut down.
65 If a specific board wants to, it can set the power down
66 code to any hardware implementation dependent code */
67 mpc52xx_halt();
68}
69
70
71void __init
72mpc52xx_set_bat(void)
73{
74 /* Set BAT 2 to map the 0xf0000000 area */
75 /* This mapping is used during mpc52xx_progress,
76 * mpc52xx_find_end_of_memory, and UARTs/GPIO access for debug
77 */
78 mb();
79 mtspr(SPRN_DBAT2U, 0xf0001ffe);
80 mtspr(SPRN_DBAT2L, 0xf000002a);
81 mb();
82}
83
84void __init
85mpc52xx_map_io(void)
86{
87 /* Here we only map the MBAR */
88 io_block_mapping(
89 MPC52xx_MBAR_VIRT, MPC52xx_MBAR, MPC52xx_MBAR_SIZE, _PAGE_IO);
90}
91
92
93#ifdef CONFIG_SERIAL_TEXT_DEBUG
94#ifndef MPC52xx_PF_CONSOLE_PORT
95#error "mpc52xx PSC for console not selected"
96#endif
97
98static void
99mpc52xx_psc_putc(struct mpc52xx_psc __iomem *psc, unsigned char c)
100{
101 while (!(in_be16(&psc->mpc52xx_psc_status) &
102 MPC52xx_PSC_SR_TXRDY));
103 out_8(&psc->mpc52xx_psc_buffer_8, c);
104}
105
106void
107mpc52xx_progress(char *s, unsigned short hex)
108{
109 char c;
110 struct mpc52xx_psc __iomem *psc;
111
112 psc = MPC52xx_VA(MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT));
113
114 while ((c = *s++) != 0) {
115 if (c == '\n')
116 mpc52xx_psc_putc(psc, '\r');
117 mpc52xx_psc_putc(psc, c);
118 }
119
120 mpc52xx_psc_putc(psc, '\r');
121 mpc52xx_psc_putc(psc, '\n');
122}
123
124#endif /* CONFIG_SERIAL_TEXT_DEBUG */
125
126
127unsigned long __init
128mpc52xx_find_end_of_memory(void)
129{
130 u32 ramsize = __res.bi_memsize;
131
132 /*
133 * if bootloader passed a memsize, just use it
134 * else get size from sdram config registers
135 */
136 if (ramsize == 0) {
137 struct mpc52xx_mmap_ctl __iomem *mmap_ctl;
138 u32 sdram_config_0, sdram_config_1;
139
140 /* Temp BAT2 mapping active when this is called ! */
141 mmap_ctl = MPC52xx_VA(MPC52xx_MMAP_CTL_OFFSET);
142
143 sdram_config_0 = in_be32(&mmap_ctl->sdram0);
144 sdram_config_1 = in_be32(&mmap_ctl->sdram1);
145
146 if ((sdram_config_0 & 0x1f) >= 0x13)
147 ramsize = 1 << ((sdram_config_0 & 0xf) + 17);
148
149 if (((sdram_config_1 & 0x1f) >= 0x13) &&
150 ((sdram_config_1 & 0xfff00000) == ramsize))
151 ramsize += 1 << ((sdram_config_1 & 0xf) + 17);
152 }
153
154 return ramsize;
155}
156
157void __init
158mpc52xx_calibrate_decr(void)
159{
160 int current_time, previous_time;
161 int tbl_start, tbl_end;
162 unsigned int xlbfreq, cpufreq, ipbfreq, pcifreq, divisor;
163
164 xlbfreq = __res.bi_busfreq;
165 /* if bootloader didn't pass bus frequencies, calculate them */
166 if (xlbfreq == 0) {
167 /* Get RTC & Clock manager modules */
168 struct mpc52xx_rtc __iomem *rtc;
169 struct mpc52xx_cdm __iomem *cdm;
170
171 rtc = ioremap(MPC52xx_PA(MPC52xx_RTC_OFFSET), MPC52xx_RTC_SIZE);
172 cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
173
174 if ((rtc==NULL) || (cdm==NULL))
175 panic("Can't ioremap RTC/CDM while computing bus freq");
176
177 /* Count bus clock during 1/64 sec */
178 out_be32(&rtc->dividers, 0x8f1f0000); /* Set RTC 64x faster */
179 previous_time = in_be32(&rtc->time);
180 while ((current_time = in_be32(&rtc->time)) == previous_time) ;
181 tbl_start = get_tbl();
182 previous_time = current_time;
183 while ((current_time = in_be32(&rtc->time)) == previous_time) ;
184 tbl_end = get_tbl();
185 out_be32(&rtc->dividers, 0xffff0000); /* Restore RTC */
186
187 /* Compute all frequency from that & CDM settings */
188 xlbfreq = (tbl_end - tbl_start) << 8;
189 cpufreq = (xlbfreq * core_mult[in_be32(&cdm->rstcfg)&0x1f])/10;
190 ipbfreq = (in_8(&cdm->ipb_clk_sel) & 1) ?
191 xlbfreq / 2 : xlbfreq;
192 switch (in_8(&cdm->pci_clk_sel) & 3) {
193 case 0:
194 pcifreq = ipbfreq;
195 break;
196 case 1:
197 pcifreq = ipbfreq / 2;
198 break;
199 default:
200 pcifreq = xlbfreq / 4;
201 break;
202 }
203 __res.bi_busfreq = xlbfreq;
204 __res.bi_intfreq = cpufreq;
205 __res.bi_ipbfreq = ipbfreq;
206 __res.bi_pcifreq = pcifreq;
207
208 /* Release mapping */
209 iounmap(rtc);
210 iounmap(cdm);
211 }
212
213 divisor = 4;
214
215 tb_ticks_per_jiffy = xlbfreq / HZ / divisor;
216 tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000);
217}
218
219int mpc52xx_match_psc_function(int psc_idx, const char *func)
220{
221 struct mpc52xx_psc_func *cf = mpc52xx_psc_functions;
222
223 while ((cf->id != -1) && (cf->func != NULL)) {
224 if ((cf->id == psc_idx) && !strcmp(cf->func,func))
225 return 1;
226 cf++;
227 }
228
229 return 0;
230}