mpc8610hpcd.c 10.3 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
	struct pci_controller *hose = &pcie1_hose;
251 252
	int pcie_configured = is_fsl_pci_cfg(LAW_TRGT_IF_PCIE_1, io_sel);
	int pcie_ep = is_fsl_pci_agent(LAW_TRGT_IF_PCIE_1, host_agent);
253
	struct pci_region *r = hose->regions;
254 255 256 257 258 259 260 261 262

	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;

		/* outbound memory */
263
		pci_set_region(r++,
264
			 CONFIG_SYS_PCIE1_MEM_BUS,
265 266
			 CONFIG_SYS_PCIE1_MEM_PHYS,
			 CONFIG_SYS_PCIE1_MEM_SIZE,
267 268 269
			 PCI_REGION_MEM);

		/* outbound io */
270
		pci_set_region(r++,
271
			 CONFIG_SYS_PCIE1_IO_BUS,
272 273
			 CONFIG_SYS_PCIE1_IO_PHYS,
			 CONFIG_SYS_PCIE1_IO_SIZE,
274 275
			 PCI_REGION_IO);

276
		hose->region_count = r - hose->regions;
277 278 279

		hose->first_busno = first_free_busno;

280
		fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295

		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
 {
296
	volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE2_ADDR;
297
	struct pci_controller *hose = &pcie2_hose;
298
	struct pci_region *r = hose->regions;
299

300 301
	int pcie_configured = is_fsl_pci_cfg(LAW_TRGT_IF_PCIE_2, io_sel);
	int pcie_ep = is_fsl_pci_agent(LAW_TRGT_IF_PCIE_2, host_agent);
302 303 304 305 306 307 308 309 310 311

	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;

		/* outbound memory */
312
		pci_set_region(r++,
313
			 CONFIG_SYS_PCIE2_MEM_BUS,
314 315
			 CONFIG_SYS_PCIE2_MEM_PHYS,
			 CONFIG_SYS_PCIE2_MEM_SIZE,
316 317 318
			 PCI_REGION_MEM);

		/* outbound io */
319
		pci_set_region(r++,
320
			 CONFIG_SYS_PCIE2_IO_BUS,
321 322
			 CONFIG_SYS_PCIE2_IO_PHYS,
			 CONFIG_SYS_PCIE2_IO_SIZE,
323 324
			 PCI_REGION_IO);

325
		hose->region_count = r - hose->regions;
326 327 328

		hose->first_busno = first_free_busno;

329
		fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
330 331 332 333 334 335 336 337 338 339 340 341 342 343

		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
 {
344
	volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCI1_ADDR;
345
	struct pci_controller *hose = &pci1_hose;
346
	int pci_agent = is_fsl_pci_agent(LAW_TRGT_IF_PCI_1, host_agent);
347
	struct pci_region *r = hose->regions;
348 349 350 351 352 353 354 355

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

		/* outbound memory */
356
		pci_set_region(r++,
357
			 CONFIG_SYS_PCI1_MEM_BUS,
358 359
			 CONFIG_SYS_PCI1_MEM_PHYS,
			 CONFIG_SYS_PCI1_MEM_SIZE,
360 361 362
			 PCI_REGION_MEM);

		/* outbound io */
363
		pci_set_region(r++,
364
			 CONFIG_SYS_PCI1_IO_BUS,
365 366
			 CONFIG_SYS_PCI1_IO_PHYS,
			 CONFIG_SYS_PCI1_IO_SIZE,
367 368
			 PCI_REGION_IO);

369
		hose->region_count = r - hose->regions;
370 371 372

		hose->first_busno = first_free_busno;

373
		fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
374 375 376 377 378 379 380 381 382 383 384 385

		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 */
}

386
#if defined(CONFIG_OF_BOARD_SETUP)
387 388 389
void
ft_board_setup(void *blob, bd_t *bd)
{
390
	ft_cpu_setup(blob, bd);
391

392
#ifdef CONFIG_PCI1
393
	ft_fsl_pci_setup(blob, "pci0", &pci1_hose);
394 395
#endif
#ifdef CONFIG_PCIE1
396
	ft_fsl_pci_setup(blob, "pci1", &pcie1_hose);
397 398
#endif
#ifdef CONFIG_PCIE2
399
	ft_fsl_pci_setup(blob, "pci2", &pcie2_hose);
400 401 402 403 404 405 406 407 408 409 410 411
#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
412
	u8 i;
413
	ulong val = 0;
414
	u8 *pixis_base = (u8 *)PIXIS_BASE;
415

416
	i = in_8(pixis_base + PIXIS_SPD);
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
	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;
}
448 449 450

int board_eth_init(bd_t *bis)
{
451
	return pci_eth_init(bis);
452
}
Peter Tyser's avatar
Peter Tyser committed
453 454 455

void board_reset(void)
{
456 457 458
	u8 *pixis_base = (u8 *)PIXIS_BASE;

	out_8(pixis_base + PIXIS_RST, 0);
Peter Tyser's avatar
Peter Tyser committed
459 460 461 462

	while (1)
		;
}