Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[linux-2.6] / arch / ppc / syslib / mpc52xx_setup.c
1 /*
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
19 #include <asm/io.h>
20 #include <asm/time.h>
21 #include <asm/mpc52xx.h>
22 #include <asm/mpc52xx_psc.h>
23 #include <asm/pgtable.h>
24 #include <asm/ppcboot.h>
25
26 #include <syslib/mpc52xx_pci.h>
27
28 extern bd_t __res;
29
30 static int core_mult[] = {              /* CPU Frequency multiplier, taken    */
31         0,  0,  0,  10, 20, 20, 25, 45, /* from the datasheet used to compute */
32         30, 55, 40, 50, 0,  60, 35, 0,  /* CPU frequency from XLB freq and    */
33         30, 25, 65, 10, 70, 20, 75, 45, /* external jumper config             */
34         0,  55, 40, 50, 80, 60, 35, 0
35 };
36
37 void
38 mpc52xx_restart(char *cmd)
39 {
40         struct mpc52xx_gpt __iomem *gpt0 = MPC52xx_VA(MPC52xx_GPTx_OFFSET(0));
41
42         local_irq_disable();
43
44         /* Turn on the watchdog and wait for it to expire. It effectively
45           does a reset */
46         out_be32(&gpt0->count, 0x000000ff);
47         out_be32(&gpt0->mode, 0x00009004);
48
49         while (1);
50 }
51
52 void
53 mpc52xx_halt(void)
54 {
55         local_irq_disable();
56
57         while (1);
58 }
59
60 void
61 mpc52xx_power_off(void)
62 {
63         /* By default we don't have any way of shut down.
64            If a specific board wants to, it can set the power down
65            code to any hardware implementation dependent code */
66         mpc52xx_halt();
67 }
68
69
70 void __init
71 mpc52xx_set_bat(void)
72 {
73         /* Set BAT 2 to map the 0xf0000000 area */
74         /* This mapping is used during mpc52xx_progress,
75          * mpc52xx_find_end_of_memory, and UARTs/GPIO access for debug
76          */
77         mb();
78         mtspr(SPRN_DBAT2U, 0xf0001ffe);
79         mtspr(SPRN_DBAT2L, 0xf000002a);
80         mb();
81 }
82
83 void __init
84 mpc52xx_map_io(void)
85 {
86         /* Here we map the MBAR and the whole upper zone. MBAR is only
87            64k but we can't map only 64k with BATs. Map the whole
88            0xf0000000 range is ok and helps eventual lpb devices placed there */
89         io_block_mapping(
90                 MPC52xx_MBAR_VIRT, MPC52xx_MBAR, 0x10000000, _PAGE_IO);
91 }
92
93
94 #ifdef CONFIG_SERIAL_TEXT_DEBUG
95 #ifndef MPC52xx_PF_CONSOLE_PORT
96 #error "mpc52xx PSC for console not selected"
97 #endif
98
99 static void
100 mpc52xx_psc_putc(struct mpc52xx_psc __iomem *psc, unsigned char c)
101 {
102         while (!(in_be16(&psc->mpc52xx_psc_status) &
103                  MPC52xx_PSC_SR_TXRDY));
104         out_8(&psc->mpc52xx_psc_buffer_8, c);
105 }
106
107 void
108 mpc52xx_progress(char *s, unsigned short hex)
109 {
110         char c;
111         struct mpc52xx_psc __iomem *psc;
112
113         psc = MPC52xx_VA(MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT));
114
115         while ((c = *s++) != 0) {
116                 if (c == '\n')
117                         mpc52xx_psc_putc(psc, '\r');
118                 mpc52xx_psc_putc(psc, c);
119         }
120
121         mpc52xx_psc_putc(psc, '\r');
122         mpc52xx_psc_putc(psc, '\n');
123 }
124
125 #endif  /* CONFIG_SERIAL_TEXT_DEBUG */
126
127
128 unsigned long __init
129 mpc52xx_find_end_of_memory(void)
130 {
131         u32 ramsize = __res.bi_memsize;
132
133         /*
134          * if bootloader passed a memsize, just use it
135          * else get size from sdram config registers
136          */
137         if (ramsize == 0) {
138                 struct mpc52xx_mmap_ctl __iomem *mmap_ctl;
139                 u32 sdram_config_0, sdram_config_1;
140
141                 /* Temp BAT2 mapping active when this is called ! */
142                 mmap_ctl = MPC52xx_VA(MPC52xx_MMAP_CTL_OFFSET);
143
144                 sdram_config_0 = in_be32(&mmap_ctl->sdram0);
145                 sdram_config_1 = in_be32(&mmap_ctl->sdram1);
146
147                 if ((sdram_config_0 & 0x1f) >= 0x13)
148                         ramsize = 1 << ((sdram_config_0 & 0xf) + 17);
149
150                 if (((sdram_config_1 & 0x1f) >= 0x13) &&
151                                 ((sdram_config_1 & 0xfff00000) == ramsize))
152                         ramsize += 1 << ((sdram_config_1 & 0xf) + 17);
153         }
154
155         return ramsize;
156 }
157
158 void __init
159 mpc52xx_calibrate_decr(void)
160 {
161         int current_time, previous_time;
162         int tbl_start, tbl_end;
163         unsigned int xlbfreq, cpufreq, ipbfreq, pcifreq, divisor;
164
165         xlbfreq = __res.bi_busfreq;
166         /* if bootloader didn't pass bus frequencies, calculate them */
167         if (xlbfreq == 0) {
168                 /* Get RTC & Clock manager modules */
169                 struct mpc52xx_rtc __iomem *rtc;
170                 struct mpc52xx_cdm __iomem *cdm;
171
172                 rtc = ioremap(MPC52xx_PA(MPC52xx_RTC_OFFSET), MPC52xx_RTC_SIZE);
173                 cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
174
175                 if ((rtc==NULL) || (cdm==NULL))
176                         panic("Can't ioremap RTC/CDM while computing bus freq");
177
178                 /* Count bus clock during 1/64 sec */
179                 out_be32(&rtc->dividers, 0x8f1f0000);   /* Set RTC 64x faster */
180                 previous_time = in_be32(&rtc->time);
181                 while ((current_time = in_be32(&rtc->time)) == previous_time) ;
182                 tbl_start = get_tbl();
183                 previous_time = current_time;
184                 while ((current_time = in_be32(&rtc->time)) == previous_time) ;
185                 tbl_end = get_tbl();
186                 out_be32(&rtc->dividers, 0xffff0000);   /* Restore RTC */
187
188                 /* Compute all frequency from that & CDM settings */
189                 xlbfreq = (tbl_end - tbl_start) << 8;
190                 cpufreq = (xlbfreq * core_mult[in_be32(&cdm->rstcfg)&0x1f])/10;
191                 ipbfreq = (in_8(&cdm->ipb_clk_sel) & 1) ?
192                                         xlbfreq / 2 : xlbfreq;
193                 switch (in_8(&cdm->pci_clk_sel) & 3) {
194                 case 0:
195                         pcifreq = ipbfreq;
196                         break;
197                 case 1:
198                         pcifreq = ipbfreq / 2;
199                         break;
200                 default:
201                         pcifreq = xlbfreq / 4;
202                         break;
203                 }
204                 __res.bi_busfreq = xlbfreq;
205                 __res.bi_intfreq = cpufreq;
206                 __res.bi_ipbfreq = ipbfreq;
207                 __res.bi_pcifreq = pcifreq;
208
209                 /* Release mapping */
210                 iounmap(rtc);
211                 iounmap(cdm);
212         }
213
214         divisor = 4;
215
216         tb_ticks_per_jiffy = xlbfreq / HZ / divisor;
217         tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000);
218 }
219
220
221 void __init
222 mpc52xx_setup_cpu(void)
223 {
224         struct mpc52xx_cdm  __iomem *cdm;
225         struct mpc52xx_xlb  __iomem *xlb;
226
227         /* Map zones */
228         cdm  = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
229         xlb  = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE);
230
231         if (!cdm || !xlb) {
232                 printk(KERN_ERR __FILE__ ": "
233                         "Error while mapping CDM/XLB during "
234                         "mpc52xx_setup_cpu\n");
235                 goto unmap_regs;
236         }
237
238         /* Use internal 48 Mhz */
239         out_8(&cdm->ext_48mhz_en, 0x00);
240         out_8(&cdm->fd_enable, 0x01);
241         if (in_be32(&cdm->rstcfg) & 0x40)       /* Assumes 33Mhz clock */
242                 out_be16(&cdm->fd_counters, 0x0001);
243         else
244                 out_be16(&cdm->fd_counters, 0x5555);
245
246         /* Configure the XLB Arbiter priorities */
247         out_be32(&xlb->master_pri_enable, 0xff);
248         out_be32(&xlb->master_priority, 0x11111111);
249
250         /* Enable ram snooping for 1GB window */
251         out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
252         out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);
253
254         /* Disable XLB pipelining */
255         /* (cfr errata 292. We could do this only just before ATA PIO
256             transaction and re-enable it after ...) */
257         out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
258
259         /* Unmap reg zone */
260 unmap_regs:
261         if (cdm)  iounmap(cdm);
262         if (xlb)  iounmap(xlb);
263 }
264
265
266 int mpc52xx_match_psc_function(int psc_idx, const char *func)
267 {
268         struct mpc52xx_psc_func *cf = mpc52xx_psc_functions;
269
270         while ((cf->id != -1) && (cf->func != NULL)) {
271                 if ((cf->id == psc_idx) && !strcmp(cf->func,func))
272                         return 1;
273                 cf++;
274         }
275
276         return 0;
277 }