]> bbs.cooldavid.org Git - net-next-2.6.git/blame - arch/ppc/syslib/mpc52xx_setup.c
[PATCH] powerpc: trivial: modify comments to refer to new location of files
[net-next-2.6.git] / arch / ppc / syslib / mpc52xx_setup.c
CommitLineData
1da177e4 1/*
1da177e4
LT
2 * Common code for the boards based on Freescale MPC52xx embedded CPU.
3 *
4 *
5 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
6 *
7 * Support for other bootloaders than UBoot by Dale Farnsworth
8 * <dfarnsworth@mvista.com>
9 *
10 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
11 * Copyright (C) 2003 Montavista Software, Inc
12 *
13 * This file is licensed under the terms of the GNU General Public License
14 * version 2. This program is licensed "as is" without any warranty of any
15 * kind, whether express or implied.
16 */
17
18#include <linux/config.h>
19
20#include <asm/io.h>
21#include <asm/time.h>
22#include <asm/mpc52xx.h>
23#include <asm/mpc52xx_psc.h>
24#include <asm/pgtable.h>
25#include <asm/ppcboot.h>
26
27extern bd_t __res;
28
29static int core_mult[] = { /* CPU Frequency multiplier, taken */
30 0, 0, 0, 10, 20, 20, 25, 45, /* from the datasheet used to compute */
31 30, 55, 40, 50, 0, 60, 35, 0, /* CPU frequency from XLB freq and */
32 30, 25, 65, 10, 70, 20, 75, 45, /* external jumper config */
33 0, 55, 40, 50, 80, 60, 35, 0
34};
35
36void
37mpc52xx_restart(char *cmd)
38{
39 struct mpc52xx_gpt __iomem *gpt0 = MPC52xx_VA(MPC52xx_GPTx_OFFSET(0));
40
41 local_irq_disable();
42
43 /* Turn on the watchdog and wait for it to expire. It effectively
44 does a reset */
45 out_be32(&gpt0->count, 0x000000ff);
46 out_be32(&gpt0->mode, 0x00009004);
47
48 while (1);
49}
50
51void
52mpc52xx_halt(void)
53{
54 local_irq_disable();
55
56 while (1);
57}
58
59void
60mpc52xx_power_off(void)
61{
62 /* By default we don't have any way of shut down.
63 If a specific board wants to, it can set the power down
64 code to any hardware implementation dependent code */
65 mpc52xx_halt();
66}
67
68
69void __init
70mpc52xx_set_bat(void)
71{
72 /* Set BAT 2 to map the 0xf0000000 area */
73 /* This mapping is used during mpc52xx_progress,
74 * mpc52xx_find_end_of_memory, and UARTs/GPIO access for debug
75 */
76 mb();
77 mtspr(SPRN_DBAT2U, 0xf0001ffe);
78 mtspr(SPRN_DBAT2L, 0xf000002a);
79 mb();
80}
81
82void __init
83mpc52xx_map_io(void)
84{
4aa7c801
SM
85 /* Here we map the MBAR and the whole upper zone. MBAR is only
86 64k but we can't map only 64k with BATs. Map the whole
87 0xf0000000 range is ok and helps eventual lpb devices placed there */
1da177e4 88 io_block_mapping(
4aa7c801 89 MPC52xx_MBAR_VIRT, MPC52xx_MBAR, 0x10000000, _PAGE_IO);
1da177e4
LT
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}