sbc8548.c 11.3 KB
Newer Older
1
/*
2 3
 * Copyright 2007,2009 Wind River Systems, Inc. <www.windriver.com>
 *
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
 * Copyright 2007 Embedded Specialties, Inc.
 *
 * Copyright 2004, 2007 Freescale Semiconductor.
 *
 * (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.com>
 *
 * 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
 */

#include <common.h>
#include <pci.h>
#include <asm/processor.h>
#include <asm/immap_85xx.h>
33
#include <asm/fsl_pci.h>
34
#include <asm/fsl_ddr_sdram.h>
35
#include <spd_sdram.h>
36 37
#include <netdev.h>
#include <tsec.h>
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
#include <miiphy.h>
#include <libfdt.h>
#include <fdt_support.h>

DECLARE_GLOBAL_DATA_PTR;

void local_bus_init(void);
void sdram_init(void);
long int fixed_sdram (void);

int board_early_init_f (void)
{
	return 0;
}

int checkboard (void)
{
55 56
	volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR);
	volatile u_char *rev= (void *)CONFIG_SYS_BD_REV;
57 58

	printf ("Board: Wind River SBC8548 Rev. 0x%01x\n",
P
Paul Gortmaker 已提交
59
			in_8(rev) >> 4);
60 61 62 63 64 65

	/*
	 * Initialize local bus.
	 */
	local_bus_init ();

P
Paul Gortmaker 已提交
66 67
	out_be32(&ecm->eedr, 0xffffffff);	/* clear ecm errors */
	out_be32(&ecm->eeer, 0xffffffff);	/* enable ecm errors */
68 69 70
	return 0;
}

71
phys_size_t
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
initdram(int board_type)
{
	long dram_size = 0;

	puts("Initializing\n");

#if defined(CONFIG_DDR_DLL)
	{
		/*
		 * Work around to stabilize DDR DLL MSYNC_IN.
		 * Errata DDR9 seems to have been fixed.
		 * This is now the workaround for Errata DDR11:
		 *    Override DLL = 1, Course Adj = 1, Tap Select = 0
		 */

87
		volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
88

P
Paul Gortmaker 已提交
89
		out_be32(&gur->ddrdllcr, 0x81000000);
90 91 92 93 94 95
		asm("sync;isync;msync");
		udelay(200);
	}
#endif

#if defined(CONFIG_SPD_EEPROM)
96 97 98
	dram_size = fsl_ddr_sdram();
	dram_size = setup_ddr_tlbs(dram_size / 0x100000);
	dram_size *= 0x100000;
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
#else
	dram_size = fixed_sdram ();
#endif

	/*
	 * SDRAM Initialization
	 */
	sdram_init();

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

/*
 * Initialize Local Bus
 */
void
local_bus_init(void)
{
118 119
	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR);
120 121 122 123 124 125

	uint clkdiv;
	uint lbc_hz;
	sys_info_t sysinfo;

	get_sys_info(&sysinfo);
P
Paul Gortmaker 已提交
126
	clkdiv = (in_be32(&lbc->lcrr) & LCRR_CLKDIV) * 2;
127 128
	lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv;

P
Paul Gortmaker 已提交
129
	out_be32(&gur->lbiuiplldcr1, 0x00078080);
130
	if (clkdiv == 16) {
P
Paul Gortmaker 已提交
131
		out_be32(&gur->lbiuiplldcr0, 0x7c0f1bf0);
132
	} else if (clkdiv == 8) {
P
Paul Gortmaker 已提交
133
		out_be32(&gur->lbiuiplldcr0, 0x6c0f1bf0);
134
	} else if (clkdiv == 4) {
P
Paul Gortmaker 已提交
135
		out_be32(&gur->lbiuiplldcr0, 0x5c0f1bf0);
136 137
	}

P
Paul Gortmaker 已提交
138
	setbits_be32(&lbc->lcrr, 0x00030000);
139 140 141

	asm("sync;isync;msync");

P
Paul Gortmaker 已提交
142 143
	out_be32(&lbc->ltesr, 0xffffffff);	/* Clear LBC error IRQs */
	out_be32(&lbc->lteir, 0xffffffff);	/* Enable LBC error IRQs */
144 145 146 147 148 149 150 151
}

/*
 * Initialize SDRAM memory on the Local Bus.
 */
void
sdram_init(void)
{
152
#if defined(CONFIG_SYS_LBC_SDRAM_SIZE)
153 154

	uint idx;
155 156
	volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR);
	uint *sdram_addr = (uint *)CONFIG_SYS_LBC_SDRAM_BASE;
157 158 159 160
	uint lsdmr_common;

	puts("    SDRAM: ");

161
	print_size (CONFIG_SYS_LBC_SDRAM_SIZE * 1024 * 1024, "\n");
162 163 164 165

	/*
	 * Setup SDRAM Base and Option Registers
	 */
P
Paul Gortmaker 已提交
166
	out_be32(&lbc->or3, CONFIG_SYS_OR3_PRELIM);
167 168
	asm("msync");

P
Paul Gortmaker 已提交
169
	out_be32(&lbc->br3, CONFIG_SYS_BR3_PRELIM);
170 171
	asm("msync");

172 173 174 175 176 177
	out_be32(&lbc->or4, CONFIG_SYS_OR4_PRELIM);
	asm("msync");

	out_be32(&lbc->br4, CONFIG_SYS_BR4_PRELIM);
	asm("msync");

P
Paul Gortmaker 已提交
178
	out_be32(&lbc->lbcr, CONFIG_SYS_LBC_LBCR);
179 180 181
	asm("msync");


P
Paul Gortmaker 已提交
182 183
	out_be32(&lbc->lsrt,  CONFIG_SYS_LBC_LSRT);
	out_be32(&lbc->mrtpr, CONFIG_SYS_LBC_MRTPR);
184 185 186 187 188
	asm("msync");

	/*
	 * MPC8548 uses "new" 15-16 style addressing.
	 */
189
	lsdmr_common = CONFIG_SYS_LBC_LSDMR_COMMON;
190
	lsdmr_common |= LSDMR_BSMA1516;
191 192 193 194

	/*
	 * Issue PRECHARGE ALL command.
	 */
P
Paul Gortmaker 已提交
195
	out_be32(&lbc->lsdmr, lsdmr_common | LSDMR_OP_PCHALL);
196 197 198 199 200 201 202 203 204
	asm("sync;msync");
	*sdram_addr = 0xff;
	ppcDcbf((unsigned long) sdram_addr);
	udelay(100);

	/*
	 * Issue 8 AUTO REFRESH commands.
	 */
	for (idx = 0; idx < 8; idx++) {
P
Paul Gortmaker 已提交
205
		out_be32(&lbc->lsdmr, lsdmr_common | LSDMR_OP_ARFRSH);
206 207 208 209 210 211 212 213 214
		asm("sync;msync");
		*sdram_addr = 0xff;
		ppcDcbf((unsigned long) sdram_addr);
		udelay(100);
	}

	/*
	 * Issue 8 MODE-set command.
	 */
P
Paul Gortmaker 已提交
215
	out_be32(&lbc->lsdmr, lsdmr_common | LSDMR_OP_MRW);
216 217 218 219 220 221 222 223
	asm("sync;msync");
	*sdram_addr = 0xff;
	ppcDcbf((unsigned long) sdram_addr);
	udelay(100);

	/*
	 * Issue NORMAL OP command.
	 */
P
Paul Gortmaker 已提交
224
	out_be32(&lbc->lsdmr, lsdmr_common | LSDMR_OP_NORMAL);
225 226 227 228 229 230 231 232
	asm("sync;msync");
	*sdram_addr = 0xff;
	ppcDcbf((unsigned long) sdram_addr);
	udelay(200);    /* Overkill. Must wait > 200 bus cycles */

#endif	/* enable SDRAM init */
}

233
#if defined(CONFIG_SYS_DRAM_TEST)
234 235 236
int
testdram(void)
{
237 238
	uint *pstart = (uint *) CONFIG_SYS_MEMTEST_START;
	uint *pend = (uint *) CONFIG_SYS_MEMTEST_END;
239 240 241
	uint *p;

	printf("Testing DRAM from 0x%08x to 0x%08x\n",
242 243
	       CONFIG_SYS_MEMTEST_START,
	       CONFIG_SYS_MEMTEST_END);
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271

	printf("DRAM test phase 1:\n");
	for (p = pstart; p < pend; p++)
		*p = 0xaaaaaaaa;

	for (p = pstart; p < pend; p++) {
		if (*p != 0xaaaaaaaa) {
			printf ("DRAM test fails at: %08x\n", (uint) p);
			return 1;
		}
	}

	printf("DRAM test phase 2:\n");
	for (p = pstart; p < pend; p++)
		*p = 0x55555555;

	for (p = pstart; p < pend; p++) {
		if (*p != 0x55555555) {
			printf ("DRAM test fails at: %08x\n", (uint) p);
			return 1;
		}
	}

	printf("DRAM test passed.\n");
	return 0;
}
#endif

P
Paul Gortmaker 已提交
272 273
#if !defined(CONFIG_SPD_EEPROM)
#define CONFIG_SYS_DDR_CONTROL 0xc300c000
274 275 276 277 278 279
/*************************************************************************
 *  fixed_sdram init -- doesn't use serial presence detect.
 *  assumes 256MB DDR2 SDRAM SODIMM, without ECC, running at DDR400 speed.
 ************************************************************************/
long int fixed_sdram (void)
{
280
	volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
281

P
Paul Gortmaker 已提交
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
	out_be32(&ddr->cs0_bnds, 0x0000007f);
	out_be32(&ddr->cs1_bnds, 0x008000ff);
	out_be32(&ddr->cs2_bnds, 0x00000000);
	out_be32(&ddr->cs3_bnds, 0x00000000);
	out_be32(&ddr->cs0_config, 0x80010101);
	out_be32(&ddr->cs1_config, 0x80010101);
	out_be32(&ddr->cs2_config, 0x00000000);
	out_be32(&ddr->cs3_config, 0x00000000);
	out_be32(&ddr->timing_cfg_3, 0x00000000);
	out_be32(&ddr->timing_cfg_0, 0x00220802);
	out_be32(&ddr->timing_cfg_1, 0x38377322);
	out_be32(&ddr->timing_cfg_2, 0x0fa044C7);
	out_be32(&ddr->sdram_cfg, 0x4300C000);
	out_be32(&ddr->sdram_cfg_2, 0x24401000);
	out_be32(&ddr->sdram_mode, 0x23C00542);
	out_be32(&ddr->sdram_mode_2, 0x00000000);
	out_be32(&ddr->sdram_interval, 0x05080100);
	out_be32(&ddr->sdram_md_cntl, 0x00000000);
	out_be32(&ddr->sdram_data_init, 0x00000000);
	out_be32(&ddr->sdram_clk_cntl, 0x03800000);
302 303 304 305 306
	asm("sync;isync;msync");
	udelay(500);

	#if defined (CONFIG_DDR_ECC)
	  /* Enable ECC checking */
P
Paul Gortmaker 已提交
307
	  out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL | 0x20000000);
308
	#else
P
Paul Gortmaker 已提交
309
	  out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL);
310 311
	#endif

312
	return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
313 314 315
}
#endif

316 317 318
#ifdef CONFIG_PCI1
static struct pci_controller pci1_hose;
#endif	/* CONFIG_PCI1 */
319 320 321 322 323 324 325 326 327 328

#ifdef CONFIG_PCIE1
static struct pci_controller pcie1_hose;
#endif	/* CONFIG_PCIE1 */

int first_free_busno=0;

void
pci_init_board(void)
{
329
	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
330 331 332

#ifdef CONFIG_PCI1
{
333
	volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCI1_ADDR;
334
	struct pci_controller *hose = &pci1_hose;
335
	struct pci_region *r = hose->regions;
336 337 338 339 340

	uint pci_32 = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_PCI32;	/* PORDEVSR[15] */
	uint pci_arb = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_ARB;	/* PORDEVSR[14] */
	uint pci_clk_sel = gur->porpllsr & MPC85xx_PORDEVSR_PCI1_SPD;	/* PORPLLSR[16] */

341
	uint pci_speed = CONFIG_SYS_CLK_FREQ;	/* get_clock_freq() */
342 343

	if (!(gur->devdisr & MPC85xx_DEVDISR_PCI1)) {
344
		printf ("    PCI host: %d bit, %s MHz, %s, %s\n",
345
			(pci_32) ? 32 : 64,
346 347
			(pci_speed == 33000000) ? "33" :
			(pci_speed == 66000000) ? "66" : "unknown",
348 349 350 351 352
			pci_clk_sel ? "sync" : "async",
			pci_arb ? "arbiter" : "external-arbiter"
			);

		/* outbound memory */
353
		pci_set_region(r++,
354 355 356
			       CONFIG_SYS_PCI1_MEM_BASE,
			       CONFIG_SYS_PCI1_MEM_PHYS,
			       CONFIG_SYS_PCI1_MEM_SIZE,
357 358 359
			       PCI_REGION_MEM);

		/* outbound io */
360
		pci_set_region(r++,
361 362 363
			       CONFIG_SYS_PCI1_IO_BASE,
			       CONFIG_SYS_PCI1_IO_PHYS,
			       CONFIG_SYS_PCI1_IO_SIZE,
364
			       PCI_REGION_IO);
365
		hose->region_count = r - hose->regions;
366 367 368

		hose->first_busno=first_free_busno;

369
		fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
370 371 372
		first_free_busno=hose->last_busno+1;
		printf ("PCI on bus %02x - %02x\n",hose->first_busno,hose->last_busno);
#ifdef CONFIG_PCIX_CHECK
P
Peter Tyser 已提交
373
		if (!(gur->pordevsr & MPC85xx_PORDEVSR_PCI1)) {
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
			/* PCI-X init */
			if (CONFIG_SYS_CLK_FREQ < 66000000)
				printf("PCI-X will only work at 66 MHz\n");

			reg16 = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
				| PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
			pci_hose_write_config_word(hose, bus, PCIX_COMMAND, reg16);
		}
#endif
	} else {
		printf ("    PCI: disabled\n");
	}
}
#else
	gur->devdisr |= MPC85xx_DEVDISR_PCI1; /* disable */
#endif

391
	gur->devdisr |= MPC85xx_DEVDISR_PCI2; /* disable PCI2 */
392 393 394

#ifdef CONFIG_PCIE1
{
395
	volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE1_ADDR;
396
	struct pci_controller *hose = &pcie1_hose;
397
	struct pci_region *r = hose->regions;
398

399
	int pcie_configured = is_fsl_pci_cfg(LAW_TRGT_IF_PCIE_1, io_sel);
400 401

	if (pcie_configured && !(gur->devdisr & MPC85xx_DEVDISR_PCIE)){
402
		printf ("\n    PCIE at base address %x",
403 404 405 406 407 408 409 410 411
			(uint)pci);

		if (pci->pme_msg_det) {
			pci->pme_msg_det = 0xffffffff;
			debug (" with errors.  Clearing.  Now 0x%08x",pci->pme_msg_det);
		}
		printf ("\n");

		/* outbound memory */
412
		pci_set_region(r++,
413 414 415
			       CONFIG_SYS_PCIE1_MEM_BASE,
			       CONFIG_SYS_PCIE1_MEM_PHYS,
			       CONFIG_SYS_PCIE1_MEM_SIZE,
416 417 418
			       PCI_REGION_MEM);

		/* outbound io */
419
		pci_set_region(r++,
420 421 422
			       CONFIG_SYS_PCIE1_IO_BASE,
			       CONFIG_SYS_PCIE1_IO_PHYS,
			       CONFIG_SYS_PCIE1_IO_SIZE,
423 424
			       PCI_REGION_IO);

425
		hose->region_count = r - hose->regions;
426 427 428

		hose->first_busno=first_free_busno;

429
		fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
430 431 432 433 434 435 436 437 438 439 440 441 442 443
		printf ("PCIE on bus %d - %d\n",hose->first_busno,hose->last_busno);

		first_free_busno=hose->last_busno+1;

	} else {
		printf ("    PCIE: disabled\n");
	}
 }
#else
	gur->devdisr |= MPC85xx_DEVDISR_PCIE; /* disable */
#endif

}

444 445 446 447 448 449 450
int board_eth_init(bd_t *bis)
{
	tsec_standard_init(bis);
	pci_eth_init(bis);
	return 0;	/* otherwise cpu_eth_init gets run */
}

451 452 453 454 455 456
int last_stage_init(void)
{
	return 0;
}

#if defined(CONFIG_OF_BOARD_SETUP)
457 458 459
void ft_board_setup(void *blob, bd_t *bd)
{
	ft_cpu_setup(blob, bd);
460
#ifdef CONFIG_PCI1
461
	ft_fsl_pci_setup(blob, "pci0", &pci1_hose);
462 463
#endif
#ifdef CONFIG_PCIE1
464
	ft_fsl_pci_setup(blob, "pci1", &pcie1_hose);
465 466 467
#endif
}
#endif