2 * Common code for the boards based on Freescale MPC52xx embedded CPU.
5 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
7 * Support for other bootloaders than UBoot by Dale Farnsworth
8 * <dfarnsworth@mvista.com>
10 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
11 * Copyright (C) 2003 Montavista Software, Inc
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.
18 #include <linux/config.h>
22 #include <asm/mpc52xx.h>
23 #include <asm/mpc52xx_psc.h>
24 #include <asm/pgtable.h>
25 #include <asm/ppcboot.h>
29 static 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
37 mpc52xx_restart(char *cmd)
39 struct mpc52xx_gpt __iomem *gpt0 = MPC52xx_VA(MPC52xx_GPTx_OFFSET(0));
43 /* Turn on the watchdog and wait for it to expire. It effectively
45 out_be32(&gpt0->count, 0x000000ff);
46 out_be32(&gpt0->mode, 0x00009004);
60 mpc52xx_power_off(void)
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 */
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
77 mtspr(SPRN_DBAT2U, 0xf0001ffe);
78 mtspr(SPRN_DBAT2L, 0xf000002a);
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 */
89 MPC52xx_MBAR_VIRT, MPC52xx_MBAR, 0x10000000, _PAGE_IO);
93 #ifdef CONFIG_SERIAL_TEXT_DEBUG
94 #ifndef MPC52xx_PF_CONSOLE_PORT
95 #error "mpc52xx PSC for console not selected"
99 mpc52xx_psc_putc(struct mpc52xx_psc __iomem *psc, unsigned char c)
101 while (!(in_be16(&psc->mpc52xx_psc_status) &
102 MPC52xx_PSC_SR_TXRDY));
103 out_8(&psc->mpc52xx_psc_buffer_8, c);
107 mpc52xx_progress(char *s, unsigned short hex)
110 struct mpc52xx_psc __iomem *psc;
112 psc = MPC52xx_VA(MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT));
114 while ((c = *s++) != 0) {
116 mpc52xx_psc_putc(psc, '\r');
117 mpc52xx_psc_putc(psc, c);
120 mpc52xx_psc_putc(psc, '\r');
121 mpc52xx_psc_putc(psc, '\n');
124 #endif /* CONFIG_SERIAL_TEXT_DEBUG */
128 mpc52xx_find_end_of_memory(void)
130 u32 ramsize = __res.bi_memsize;
133 * if bootloader passed a memsize, just use it
134 * else get size from sdram config registers
137 struct mpc52xx_mmap_ctl __iomem *mmap_ctl;
138 u32 sdram_config_0, sdram_config_1;
140 /* Temp BAT2 mapping active when this is called ! */
141 mmap_ctl = MPC52xx_VA(MPC52xx_MMAP_CTL_OFFSET);
143 sdram_config_0 = in_be32(&mmap_ctl->sdram0);
144 sdram_config_1 = in_be32(&mmap_ctl->sdram1);
146 if ((sdram_config_0 & 0x1f) >= 0x13)
147 ramsize = 1 << ((sdram_config_0 & 0xf) + 17);
149 if (((sdram_config_1 & 0x1f) >= 0x13) &&
150 ((sdram_config_1 & 0xfff00000) == ramsize))
151 ramsize += 1 << ((sdram_config_1 & 0xf) + 17);
158 mpc52xx_calibrate_decr(void)
160 int current_time, previous_time;
161 int tbl_start, tbl_end;
162 unsigned int xlbfreq, cpufreq, ipbfreq, pcifreq, divisor;
164 xlbfreq = __res.bi_busfreq;
165 /* if bootloader didn't pass bus frequencies, calculate them */
167 /* Get RTC & Clock manager modules */
168 struct mpc52xx_rtc __iomem *rtc;
169 struct mpc52xx_cdm __iomem *cdm;
171 rtc = ioremap(MPC52xx_PA(MPC52xx_RTC_OFFSET), MPC52xx_RTC_SIZE);
172 cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
174 if ((rtc==NULL) || (cdm==NULL))
175 panic("Can't ioremap RTC/CDM while computing bus freq");
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) ;
185 out_be32(&rtc->dividers, 0xffff0000); /* Restore RTC */
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) {
197 pcifreq = ipbfreq / 2;
200 pcifreq = xlbfreq / 4;
203 __res.bi_busfreq = xlbfreq;
204 __res.bi_intfreq = cpufreq;
205 __res.bi_ipbfreq = ipbfreq;
206 __res.bi_pcifreq = pcifreq;
208 /* Release mapping */
215 tb_ticks_per_jiffy = xlbfreq / HZ / divisor;
216 tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000);
219 int mpc52xx_match_psc_function(int psc_idx, const char *func)
221 struct mpc52xx_psc_func *cf = mpc52xx_psc_functions;
223 while ((cf->id != -1) && (cf->func != NULL)) {
224 if ((cf->id == psc_idx) && !strcmp(cf->func,func))