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
28extern bd_t __res;
29
30static 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
37void
38mpc52xx_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
52void
53mpc52xx_halt(void)
54{
55	local_irq_disable();
56
57	while (1);
58}
59
60void
61mpc52xx_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
70void __init
71mpc52xx_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
83void __init
84mpc52xx_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
99static void
100mpc52xx_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
107void
108mpc52xx_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
128unsigned long __init
129mpc52xx_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
158void __init
159mpc52xx_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
221void __init
222mpc52xx_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 */
260unmap_regs:
261	if (cdm)  iounmap(cdm);
262	if (xlb)  iounmap(xlb);
263}
264
265
266int 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}
278