2 * arch/ppc/syslib/mpc52xx_setup.c
4 * Common code for the boards based on Freescale MPC52xx embedded CPU.
7 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
9 * Support for other bootloaders than UBoot by Dale Farnsworth
10 * <dfarnsworth@mvista.com>
12 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
13 * Copyright (C) 2003 Montavista Software, Inc
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.
20 #include <linux/config.h>
24 #include <asm/mpc52xx.h>
25 #include <asm/mpc52xx_psc.h>
26 #include <asm/pgtable.h>
27 #include <asm/ppcboot.h>
31 static 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
39 mpc52xx_restart(char *cmd
)
41 struct mpc52xx_gpt __iomem
*gpt0
= MPC52xx_VA(MPC52xx_GPTx_OFFSET(0));
45 /* Turn on the watchdog and wait for it to expire. It effectively
47 out_be32(&gpt0
->count
, 0x000000ff);
48 out_be32(&gpt0
->mode
, 0x00009004);
62 mpc52xx_power_off(void)
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 */
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
79 mtspr(SPRN_DBAT2U
, 0xf0001ffe);
80 mtspr(SPRN_DBAT2L
, 0xf000002a);
87 /* Here we only map the MBAR */
89 MPC52xx_MBAR_VIRT
, MPC52xx_MBAR
, MPC52xx_MBAR_SIZE
, _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
))