mpc8610hpcd.c 11 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * Copyright 2007 Freescale Semiconductor, Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
22

23
24
25
26
27
#include <common.h>
#include <command.h>
#include <pci.h>
#include <asm/processor.h>
#include <asm/immap_86xx.h>
28
#include <asm/fsl_pci.h>
29
#include <asm/fsl_ddr_sdram.h>
30
#include <i2c.h>
31
#include <asm/io.h>
32
33
#include <libfdt.h>
#include <fdt_support.h>
34
#include <spd_sdram.h>
35
#include <netdev.h>
36
37
38
39

#include "../common/pixis.h"

void sdram_init(void);
40
phys_size_t fixed_sdram(void);
41
42
void mpc8610hpcd_diu_init(void);

43
44
45
46

/* called before any console output */
int board_early_init_f(void)
{
47
	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
48
49
	volatile ccsr_gur_t *gur = &immap->im_gur;

York Sun's avatar
York Sun committed
50
51
52
53
54
55
56
57
	gur->gpiocr |= 0x88aa5500; /* DIU16, IR1, UART0, UART2 */

	return 0;
}

int misc_init_r(void)
{
	u8 tmp_val, version;
58
	u8 *pixis_base = (u8 *)PIXIS_BASE;
York Sun's avatar
York Sun committed
59
60

	/*Do not use 8259PIC*/
61
62
	tmp_val = in_8(pixis_base + PIXIS_BRDCFG0);
	out_8(pixis_base + PIXIS_BRDCFG0, tmp_val | 0x80);
York Sun's avatar
York Sun committed
63
64

	/*For FPGA V7 or higher, set the IRQMAPSEL to 0 to use MAP0 interrupt*/
65
	version = in_8(pixis_base + PIXIS_PVER);
York Sun's avatar
York Sun committed
66
	if(version >= 0x07) {
67
68
		tmp_val = in_8(pixis_base + PIXIS_BRDCFG0);
		out_8(pixis_base + PIXIS_BRDCFG0, tmp_val & 0xbf);
York Sun's avatar
York Sun committed
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
	}

	/* Using this for DIU init before the driver in linux takes over
	 *  Enable the TFP410 Encoder (I2C address 0x38)
	 */

	tmp_val = 0xBF;
	i2c_write(0x38, 0x08, 1, &tmp_val, sizeof(tmp_val));
	/* Verify if enabled */
	tmp_val = 0;
	i2c_read(0x38, 0x08, 1, &tmp_val, sizeof(tmp_val));
	debug("DVI Encoder Read: 0x%02lx\n",tmp_val);

	tmp_val = 0x10;
	i2c_write(0x38, 0x0A, 1, &tmp_val, sizeof(tmp_val));
	/* Verify if enabled */
	tmp_val = 0;
	i2c_read(0x38, 0x0A, 1, &tmp_val, sizeof(tmp_val));
	debug("DVI Encoder Read: 0x%02lx\n",tmp_val);

#ifdef CONFIG_FSL_DIU_FB
	mpc8610hpcd_diu_init();
#endif
92
93
94
95
96
97

	return 0;
}

int checkboard(void)
{
98
	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
99
	volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
100
	u8 *pixis_base = (u8 *)PIXIS_BASE;
101

102
103
	printf ("Board: MPC8610HPCD, System ID: 0x%02x, "
		"System Version: 0x%02x, FPGA Version: 0x%02x\n",
104
105
		in_8(pixis_base + PIXIS_ID), in_8(pixis_base + PIXIS_VER),
		in_8(pixis_base + PIXIS_PVER));
106
107
108
109
110
111
112
113
114
115
116
117
118

	mcm->abcr |= 0x00010000; /* 0 */
	mcm->hpmr3 = 0x80000008; /* 4c */
	mcm->hpmr0 = 0;
	mcm->hpmr1 = 0;
	mcm->hpmr2 = 0;
	mcm->hpmr4 = 0;
	mcm->hpmr5 = 0;

	return 0;
}


119
phys_size_t
120
121
initdram(int board_type)
{
122
	phys_size_t dram_size = 0;
123
124

#if defined(CONFIG_SPD_EEPROM)
125
	dram_size = fsl_ddr_sdram();
126
127
128
129
#else
	dram_size = fixed_sdram();
#endif

130
#if defined(CONFIG_SYS_RAMBOOT)
131
132
133
134
135
136
137
138
139
140
141
142
143
144
	puts(" DDR: ");
	return dram_size;
#endif

	puts(" DDR: ");
	return dram_size;
}


#if !defined(CONFIG_SPD_EEPROM)
/*
 * Fixed sdram init -- doesn't use serial presence detect.
 */

145
phys_size_t fixed_sdram(void)
146
{
147
148
#if !defined(CONFIG_SYS_RAMBOOT)
	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
149
150
151
152
153
154
	volatile ccsr_ddr_t *ddr = &immap->im_ddr1;
	uint d_init;

	ddr->cs0_bnds = 0x0000001f;
	ddr->cs0_config = 0x80010202;

155
	ddr->timing_cfg_3 = 0x00000000;
156
157
158
	ddr->timing_cfg_0 = 0x00260802;
	ddr->timing_cfg_1 = 0x3935d322;
	ddr->timing_cfg_2 = 0x14904cc8;
159
	ddr->sdram_mode = 0x00480432;
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
	ddr->sdram_mode_2 = 0x00000000;
	ddr->sdram_interval = 0x06180fff; /* 0x06180100; */
	ddr->sdram_data_init = 0xDEADBEEF;
	ddr->sdram_clk_cntl = 0x03800000;
	ddr->sdram_cfg_2 = 0x04400010;

#if defined(CONFIG_DDR_ECC)
	ddr->err_int_en = 0x0000000d;
	ddr->err_disable = 0x00000000;
	ddr->err_sbe = 0x00010000;
#endif
	asm("sync;isync");

	udelay(500);

175
	ddr->sdram_cfg = 0xc3000000; /* 0xe3008000;*/
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194


#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
	d_init = 1;
	debug("DDR - 1st controller: memory initializing\n");
	/*
	 * Poll until memory is initialized.
	 * 512 Meg at 400 might hit this 200 times or so.
	 */
	while ((ddr->sdram_cfg_2 & (d_init << 4)) != 0)
		udelay(1000);

	debug("DDR: memory initialized\n\n");
	asm("sync; isync");
	udelay(500);
#endif

	return 512 * 1024 * 1024;
#endif
195
	return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
}

#endif

#if defined(CONFIG_PCI)
/*
 * Initialize PCI Devices, report devices found.
 */

#ifndef CONFIG_PCI_PNP
static struct pci_config_table pci_fsl86xxads_config_table[] = {
	{PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
	 PCI_IDSEL_NUMBER, PCI_ANY_ID,
	 pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
				 PCI_ENET0_MEMADDR,
				 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER} },
	{}
};
#endif


static struct pci_controller pci1_hose = {
#ifndef CONFIG_PCI_PNP
config_table:pci_mpc86xxcts_config_table
#endif
};
#endif /* CONFIG_PCI */

#ifdef CONFIG_PCIE1
static struct pci_controller pcie1_hose;
#endif

#ifdef CONFIG_PCIE2
static struct pci_controller pcie2_hose;
#endif

int first_free_busno = 0;

void pci_init_board(void)
{
236
	volatile immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR;
237
238
	volatile ccsr_gur_t *gur = &immap->im_gur;
	uint devdisr = gur->devdisr;
239
240
241
242
	uint io_sel = (gur->pordevsr & MPC8610_PORDEVSR_IO_SEL)
		>> MPC8610_PORDEVSR_IO_SEL_SHIFT;
	uint host_agent = (gur->porbmsr & MPC8610_PORBMSR_HA)
		>> MPC8610_PORBMSR_HA_SHIFT;
243
244
245
246
247
248

	printf( " pci_init_board: devdisr=%x, io_sel=%x, host_agent=%x\n",
		devdisr, io_sel, host_agent);

#ifdef CONFIG_PCIE1
 {
249
	volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE1_ADDR;
250
251
252
253
	struct pci_controller *hose = &pcie1_hose;
	int pcie_configured = (io_sel == 1) || (io_sel == 4);
	int pcie_ep = (host_agent == 0) || (host_agent == 2) ||
		(host_agent == 5);
254
	struct pci_region *r = hose->regions;
255
256
257
258
259
260
261
262
263

	if (pcie_configured && !(devdisr & MPC86xx_DEVDISR_PCIE1)) {
		printf(" PCIe 1 connected to Uli as %s (base address %x)\n",
			pcie_ep ? "End Point" : "Root Complex",
			(uint)pci);
		if (pci->pme_msg_det)
			pci->pme_msg_det = 0xffffffff;

		/* inbound */
264
		r += fsl_pci_setup_inbound_windows(r);
265
266

		/* outbound memory */
267
		pci_set_region(r++,
268
			 CONFIG_SYS_PCIE1_MEM_BUS,
269
270
			 CONFIG_SYS_PCIE1_MEM_PHYS,
			 CONFIG_SYS_PCIE1_MEM_SIZE,
271
272
273
			 PCI_REGION_MEM);

		/* outbound io */
274
		pci_set_region(r++,
275
			 CONFIG_SYS_PCIE1_IO_BUS,
276
277
			 CONFIG_SYS_PCIE1_IO_PHYS,
			 CONFIG_SYS_PCIE1_IO_SIZE,
278
279
			 PCI_REGION_IO);

280
		hose->region_count = r - hose->regions;
281
282
283

		hose->first_busno = first_free_busno;

284
		fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299

		first_free_busno = hose->last_busno + 1;
		printf(" PCI-Express 1 on bus %02x - %02x\n",
			hose->first_busno, hose->last_busno);

	} else
		puts(" PCI-Express 1: Disabled\n");
 }
#else
	puts("PCI-Express 1: Disabled\n");
#endif /* CONFIG_PCIE1 */


#ifdef CONFIG_PCIE2
 {
300
	volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE2_ADDR;
301
	struct pci_controller *hose = &pcie2_hose;
302
	struct pci_region *r = hose->regions;
303
304
305
306
307
308
309
310
311
312
313
314
315
316

	int pcie_configured = (io_sel == 0) || (io_sel == 4);
	int pcie_ep = (host_agent == 0) || (host_agent == 1) ||
		(host_agent == 4);

	if (pcie_configured && !(devdisr & MPC86xx_DEVDISR_PCIE2)) {
		printf(" PCI-Express 2 connected to slot as %s" \
			" (base address %x)\n",
			pcie_ep ? "End Point" : "Root Complex",
			(uint)pci);
		if (pci->pme_msg_det)
			pci->pme_msg_det = 0xffffffff;

		/* inbound */
317
		r += fsl_pci_setup_inbound_windows(r);
318
319

		/* outbound memory */
320
		pci_set_region(r++,
321
			 CONFIG_SYS_PCIE2_MEM_BUS,
322
323
			 CONFIG_SYS_PCIE2_MEM_PHYS,
			 CONFIG_SYS_PCIE2_MEM_SIZE,
324
325
326
			 PCI_REGION_MEM);

		/* outbound io */
327
		pci_set_region(r++,
328
			 CONFIG_SYS_PCIE2_IO_BUS,
329
330
			 CONFIG_SYS_PCIE2_IO_PHYS,
			 CONFIG_SYS_PCIE2_IO_SIZE,
331
332
			 PCI_REGION_IO);

333
		hose->region_count = r - hose->regions;
334
335
336

		hose->first_busno = first_free_busno;

337
		fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
338
339
340
341
342
343
344
345
346
347
348
349
350
351

		first_free_busno = hose->last_busno + 1;
		printf(" PCI-Express 2 on bus %02x - %02x\n",
			hose->first_busno, hose->last_busno);
	} else
		puts(" PCI-Express 2: Disabled\n");
 }
#else
	puts("PCI-Express 2: Disabled\n");
#endif /* CONFIG_PCIE2 */


#ifdef CONFIG_PCI1
 {
352
	volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCI1_ADDR;
353
354
	struct pci_controller *hose = &pci1_hose;
	int pci_agent = (host_agent >= 4) && (host_agent <= 6);
355
	struct pci_region *r = hose->regions;
356
357
358
359
360
361
362
363

	if ( !(devdisr & MPC86xx_DEVDISR_PCI1)) {
		printf(" PCI connected to PCI slots as %s" \
			" (base address %x)\n",
			pci_agent ? "Agent" : "Host",
			(uint)pci);

		/* inbound */
364
		r += fsl_pci_setup_inbound_windows(r);
365
366

		/* outbound memory */
367
		pci_set_region(r++,
368
			 CONFIG_SYS_PCI1_MEM_BUS,
369
370
			 CONFIG_SYS_PCI1_MEM_PHYS,
			 CONFIG_SYS_PCI1_MEM_SIZE,
371
372
373
			 PCI_REGION_MEM);

		/* outbound io */
374
		pci_set_region(r++,
375
			 CONFIG_SYS_PCI1_IO_BUS,
376
377
			 CONFIG_SYS_PCI1_IO_PHYS,
			 CONFIG_SYS_PCI1_IO_SIZE,
378
379
			 PCI_REGION_IO);

380
		hose->region_count = r - hose->regions;
381
382
383

		hose->first_busno = first_free_busno;

384
		fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
385
386
387
388
389
390
391
392
393
394
395
396

		first_free_busno = hose->last_busno + 1;
		printf(" PCI on bus %02x - %02x\n",
			hose->first_busno, hose->last_busno);


	} else
		puts(" PCI: Disabled\n");
 }
#endif /* CONFIG_PCI1 */
}

397
#if defined(CONFIG_OF_BOARD_SETUP)
398
399
400
void
ft_board_setup(void *blob, bd_t *bd)
{
401
402
403
404
405
406
407
408
	do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
			     "timebase-frequency", bd->bi_busfreq / 4, 1);
	do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
			     "bus-frequency", bd->bi_busfreq, 1);
	do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
			     "clock-frequency", bd->bi_intfreq, 1);
	do_fixup_by_prop_u32(blob, "device_type", "soc", 4,
			     "bus-frequency", bd->bi_busfreq, 1);
409

410
411
412
413
414
	do_fixup_by_compat_u32(blob, "ns16550",
			       "clock-frequency", bd->bi_busfreq, 1);

	fdt_fixup_memory(blob, bd->bi_memstart, bd->bi_memsize);

415
#ifdef CONFIG_PCI1
416
	ft_fsl_pci_setup(blob, "pci0", &pci1_hose);
417
418
#endif
#ifdef CONFIG_PCIE1
419
	ft_fsl_pci_setup(blob, "pci1", &pcie1_hose);
420
421
#endif
#ifdef CONFIG_PCIE2
422
	ft_fsl_pci_setup(blob, "pci2", &pcie2_hose);
423
424
425
426
427
428
429
430
431
432
433
434
#endif
}
#endif

/*
 * get_board_sys_clk
 * Reads the FPGA on board for CONFIG_SYS_CLK_FREQ
 */

unsigned long
get_board_sys_clk(ulong dummy)
{
York Sun's avatar
York Sun committed
435
	u8 i;
436
	ulong val = 0;
437
	u8 *pixis_base = (u8 *)PIXIS_BASE;
438

439
	i = in_8(pixis_base + PIXIS_SPD);
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
	i &= 0x07;

	switch (i) {
	case 0:
		val = 33333000;
		break;
	case 1:
		val = 39999600;
		break;
	case 2:
		val = 49999500;
		break;
	case 3:
		val = 66666000;
		break;
	case 4:
		val = 83332500;
		break;
	case 5:
		val = 99999000;
		break;
	case 6:
		val = 133332000;
		break;
	case 7:
		val = 166665000;
		break;
	}

	return val;
}
471
472
473

int board_eth_init(bd_t *bis)
{
474
	return pci_eth_init(bis);
475
}
Peter Tyser's avatar
Peter Tyser committed
476
477
478

void board_reset(void)
{
479
480
481
	u8 *pixis_base = (u8 *)PIXIS_BASE;

	out_8(pixis_base + PIXIS_RST, 0);
Peter Tyser's avatar
Peter Tyser committed
482
483
484
485

	while (1)
		;
}