[PATCH] Update AMCC Yucca 440SPe eval board support

The AMCC Yucca now uses the common 440SP(e) DDR SPD code for DDR
inititializition. This includes DDR auto calibration and support
for different DIMM modules, instead of the fixed setup used in
the earlier version.

Signed-off-by: Stefan Roese <sr@denx.de>
This commit is contained in:
Stefan Roese 2007-03-08 10:10:18 +01:00
parent 2721a68a9e
commit 2f5df47351
3 changed files with 35 additions and 378 deletions

View file

@ -1,4 +1,7 @@
/*
* (C) Copyright 2007
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.com>
*
* See file CREDITS for list of people who contributed to this
@ -19,56 +22,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/* port to AMCC 440SPE evaluatioon board - SG April 12,2005 */
#include <ppc_asm.tmpl>
#include <config.h>
/* General */
#define TLB_VALID 0x00000200
/* Supported page sizes */
#define SZ_1K 0x00000000
#define SZ_4K 0x00000010
#define SZ_16K 0x00000020
#define SZ_64K 0x00000030
#define SZ_256K 0x00000040
#define SZ_1M 0x00000050
#define SZ_16M 0x00000070
#define SZ_256M 0x00000090
/* Storage attributes */
#define SA_W 0x00000800 /* Write-through */
#define SA_I 0x00000400 /* Caching inhibited */
#define SA_M 0x00000200 /* Memory coherence */
#define SA_G 0x00000100 /* Guarded */
#define SA_E 0x00000080 /* Endian */
/* Access control */
#define AC_X 0x00000024 /* Execute */
#define AC_W 0x00000012 /* Write */
#define AC_R 0x00000009 /* Read */
/* Some handy macros */
#define EPN(e) ((e) & 0xfffffc00)
#define TLB0(epn,sz) ((EPN((epn)) | (sz) | TLB_VALID ))
#define TLB1(rpn,erpn) (((rpn) & 0xfffffc00) | (erpn))
#define TLB2(a) ((a) & 0x00000fbf)
#define tlbtab_start\
mflr r1 ;\
bl 0f ;
#define tlbtab_end\
.long 0, 0, 0 ;\
0: mflr r0 ;\
mtlr r1 ;\
blr ;
#define tlbentry(epn,sz,rpn,erpn,attr)\
.long TLB0(epn,sz),TLB1(rpn,erpn),TLB2(attr)
#include <asm-ppc/mmu.h>
/**************************************************************************
* TLB TABLE
@ -89,12 +46,18 @@
.globl tlbtabA
tlbtabA:
tlbtab_start
tlbentry(0xfff00000, SZ_16M, 0xfff00000, 4, AC_R|AC_W|AC_X|SA_G)
tlbentry(CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
tlbentry(CFG_SDRAM_BASE + 0x10000000, SZ_256M, 0x10000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
tlbentry(CFG_SDRAM_BASE + 0x20000000, SZ_256M, 0x20000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
tlbentry(CFG_SDRAM_BASE + 0x30000000, SZ_256M, 0x30000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
/*
* BOOT_CS (FLASH) must be first. Before relocation SA_I can be off to use the
* speed up boot process. It is patched after relocation to enable SA_I
*/
tlbentry(0xff000000, SZ_16M, 0xff000000, 4, AC_R|AC_W|AC_X|SA_G)
/*
* TLB entries for SDRAM are not needed on this platform.
* They are dynamically generated in the SPD DDR(2) detection
* routine.
*/
tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I)
tlbentry(CFG_FPGA_BASE, SZ_1K, 0xE2000000, 4,AC_R|AC_W|SA_I)
@ -126,12 +89,18 @@ tlbtabA:
.globl tlbtabB
tlbtabB:
tlbtab_start
tlbentry(0xfff00000, SZ_16M, 0xfff00000, 4, AC_R|AC_W|AC_X|SA_G)
tlbentry(CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
tlbentry(CFG_SDRAM_BASE + 0x10000000, SZ_256M, 0x10000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
tlbentry(CFG_SDRAM_BASE + 0x20000000, SZ_256M, 0x20000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
tlbentry(CFG_SDRAM_BASE + 0x30000000, SZ_256M, 0x30000000, 0, AC_R|AC_W|AC_X|SA_G|SA_I)
/*
* BOOT_CS (FLASH) must be first. Before relocation SA_I can be off to use the
* speed up boot process. It is patched after relocation to enable SA_I
*/
tlbentry(0xff000000, SZ_16M, 0xff000000, 4, AC_R|AC_W|AC_X|SA_G)
/*
* TLB entries for SDRAM are not needed on this platform.
* They are dynamically generated in the SPD DDR(2) detection
* routine.
*/
tlbentry(CFG_ISRAM_BASE, SZ_256K, 0x00000000, 4, AC_R|AC_W|AC_X|SA_I)
tlbentry(CFG_FPGA_BASE, SZ_1K, 0xE2000000, 4,AC_R|AC_W|SA_I)

View file

@ -44,8 +44,6 @@ int compare_to_true(char *str );
char *remove_l_w_space(char *in_str );
char *remove_t_w_space(char *in_str );
int get_console_port(void);
unsigned long ppcMfcpr(unsigned long cpr_reg);
unsigned long ppcMfsdr(unsigned long sdr_reg);
int ppc440spe_init_pcie_rootport(int port);
void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
@ -221,7 +219,7 @@ int board_early_init_f (void)
|
+-------------------------------------------------------------------*/
/* Read Pin Strap Register in PPC440SP */
sdr0_pinstp = ppcMfsdr(SDR0_PINSTP);
mfsdr(SDR0_PINSTP, sdr0_pinstp);
bootstrap_settings = sdr0_pinstp & SDR0_PINSTP_BOOTSTRAP_MASK;
switch (bootstrap_settings) {
@ -246,7 +244,7 @@ int board_early_init_f (void)
* Boot Settings in IIC EEprom address 0x50 or 0x54
* Read Serial Device Strap Register1 in PPC440SPe
*/
sdr0_sdstp1 = ppcMfsdr(SDR0_SDSTP1);
mfsdr(SDR0_SDSTP1, sdr0_sdstp1);
boot_selection = sdr0_sdstp1 & SDR0_SDSTP1_ERPN_MASK;
ebc_data_width = sdr0_sdstp1 & SDR0_SDSTP1_EBCW_MASK;
@ -564,277 +562,6 @@ int checkboard (void)
return 0;
}
static long int yucca_probe_for_dimms(void)
{
int dimm_installed[MAXDIMMS];
int dimm_num, result;
int dimms_found = 0;
uchar dimm_addr = IIC0_DIMM0_ADDR;
uchar dimm_spd_data[MAX_SPD_BYTES];
for (dimm_num = 0; dimm_num < MAXDIMMS; dimm_num++) {
/* check if there is a chip at the dimm address */
switch (dimm_num) {
case 0:
dimm_addr = IIC0_DIMM0_ADDR;
break;
case 1:
dimm_addr = IIC0_DIMM1_ADDR;
break;
}
result = i2c_probe(dimm_addr);
memset(dimm_spd_data, 0, MAX_SPD_BYTES * sizeof(char));
if (result == 0) {
/* read first byte of SPD data, if there is any data */
result = i2c_read(dimm_addr, 0, 1, dimm_spd_data, 1);
if (result == 0) {
result = dimm_spd_data[0];
result = result > MAX_SPD_BYTES ?
MAX_SPD_BYTES : result;
result = i2c_read(dimm_addr, 0, 1,
dimm_spd_data, result);
}
}
if ((result == 0) &&
(dimm_spd_data[64] == MICRON_SPD_JEDEC_ID)) {
dimm_installed[dimm_num] = TRUE;
dimms_found++;
debug("DIMM slot %d: DDR2 SDRAM detected\n", dimm_num);
} else {
dimm_installed[dimm_num] = FALSE;
debug("DIMM slot %d: Not populated or cannot sucessfully probe the DIMM\n", dimm_num);
}
}
if (dimms_found == 0) {
printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n");
hang();
}
if (dimm_installed[0] != TRUE) {
printf("\nERROR - DIMM slot 0 must be populated before DIMM slot 1.\n");
printf(" Unsupported configuration. Move DIMM module from DIMM slot 1 to slot 0.\n\n");
hang();
}
return dimms_found;
}
/*************************************************************************
* init SDRAM controller with fixed value
* the initialization values are for 2x MICRON DDR2
* PN: MT18HTF6472DY-53EB2
* 512MB, DDR2, 533, CL4, ECC, REG
************************************************************************/
static long int fixed_sdram(void)
{
long int yucca_dimms = 0;
yucca_dimms = yucca_probe_for_dimms();
/* SDRAM0_MCOPT2 (0X21) Clear DCEN BIT */
mtdcr( 0x10, 0x00000021 );
mtdcr( 0x11, 0x84000000 );
/* SDRAM0_MCOPT1 (0X20) ECC OFF / 64 bits / 4 banks / DDR2 */
mtdcr( 0x10, 0x00000020 );
mtdcr( 0x11, 0x2D122000 );
/* SET MCIF0_CODT Die Termination On */
mtdcr( 0x10, 0x00000026 );
if (yucca_dimms == 2)
mtdcr( 0x11, 0x2A800021 );
else if (yucca_dimms == 1)
mtdcr( 0x11, 0x02800021 );
/* On-Die Termination for Bank 0 */
mtdcr( 0x10, 0x00000022 );
if (yucca_dimms == 2)
mtdcr( 0x11, 0x18000000 );
else if (yucca_dimms == 1)
mtdcr( 0x11, 0x06000000 );
/* On-Die Termination for Bank 1 */
mtdcr( 0x10, 0x00000023 );
if (yucca_dimms == 2)
mtdcr( 0x11, 0x18000000 );
else if (yucca_dimms == 1)
mtdcr( 0x11, 0x01800000 );
/* On-Die Termination for Bank 2 */
mtdcr( 0x10, 0x00000024 );
if (yucca_dimms == 2)
mtdcr( 0x11, 0x01800000 );
else if (yucca_dimms == 1)
mtdcr( 0x11, 0x00000000 );
/* On-Die Termination for Bank 3 */
mtdcr( 0x10, 0x00000025 );
if (yucca_dimms == 2)
mtdcr( 0x11, 0x01800000 );
else if (yucca_dimms == 1)
mtdcr( 0x11, 0x00000000 );
/* Refresh Time register (0x30) Refresh every 7.8125uS */
mtdcr( 0x10, 0x00000030 );
mtdcr( 0x11, 0x08200000 );
/* SET MCIF0_MMODE CL 4 */
mtdcr( 0x10, 0x00000088 );
mtdcr( 0x11, 0x00000642 );
/* MCIF0_MEMODE */
mtdcr( 0x10, 0x00000089 );
mtdcr( 0x11, 0x00000004 );
/*SET MCIF0_MB0CF */
mtdcr( 0x10, 0x00000040 );
mtdcr( 0x11, 0x00000201 );
/* SET MCIF0_MB1CF */
mtdcr( 0x10, 0x00000044 );
mtdcr( 0x11, 0x00000201 );
/* SET MCIF0_MB2CF */
mtdcr( 0x10, 0x00000048 );
if (yucca_dimms == 2)
mtdcr( 0x11, 0x00000201 );
else if (yucca_dimms == 1)
mtdcr( 0x11, 0x00000000 );
/* SET MCIF0_MB3CF */
mtdcr( 0x10, 0x0000004c );
if (yucca_dimms == 2)
mtdcr( 0x11, 0x00000201 );
else if (yucca_dimms == 1)
mtdcr( 0x11, 0x00000000 );
/* SET MCIF0_INITPLR0 # NOP */
mtdcr( 0x10, 0x00000050 );
mtdcr( 0x11, 0xB5380000 );
/* SET MCIF0_INITPLR1 # PRE */
mtdcr( 0x10, 0x00000051 );
mtdcr( 0x11, 0x82100400 );
/* SET MCIF0_INITPLR2 # EMR2 */
mtdcr( 0x10, 0x00000052 );
mtdcr( 0x11, 0x80820000 );
/* SET MCIF0_INITPLR3 # EMR3 */
mtdcr( 0x10, 0x00000053 );
mtdcr( 0x11, 0x80830000 );
/* SET MCIF0_INITPLR4 # EMR DLL ENABLE */
mtdcr( 0x10, 0x00000054 );
mtdcr( 0x11, 0x80810000 );
/* SET MCIF0_INITPLR5 # MR DLL RESET */
mtdcr( 0x10, 0x00000055 );
mtdcr( 0x11, 0x80800542 );
/* SET MCIF0_INITPLR6 # PRE */
mtdcr( 0x10, 0x00000056 );
mtdcr( 0x11, 0x82100400 );
/* SET MCIF0_INITPLR7 # Refresh */
mtdcr( 0x10, 0x00000057 );
mtdcr( 0x11, 0x8A080000 );
/* SET MCIF0_INITPLR8 # Refresh */
mtdcr( 0x10, 0x00000058 );
mtdcr( 0x11, 0x8A080000 );
/* SET MCIF0_INITPLR9 # Refresh */
mtdcr( 0x10, 0x00000059 );
mtdcr( 0x11, 0x8A080000 );
/* SET MCIF0_INITPLR10 # Refresh */
mtdcr( 0x10, 0x0000005A );
mtdcr( 0x11, 0x8A080000 );
/* SET MCIF0_INITPLR11 # MR */
mtdcr( 0x10, 0x0000005B );
mtdcr( 0x11, 0x80800442 );
/* SET MCIF0_INITPLR12 # EMR OCD Default*/
mtdcr( 0x10, 0x0000005C );
mtdcr( 0x11, 0x80810380 );
/* SET MCIF0_INITPLR13 # EMR OCD Exit */
mtdcr( 0x10, 0x0000005D );
mtdcr( 0x11, 0x80810000 );
/* 0x80: Adv Addr clock by 180 deg */
mtdcr( 0x10, 0x00000080 );
mtdcr( 0x11, 0x80000000 );
/* 0x21: Exit self refresh, set DC_EN */
mtdcr( 0x10, 0x00000021 );
mtdcr( 0x11, 0x28000000 );
/* 0x81: Write DQS Adv 90 + Fractional DQS Delay */
mtdcr( 0x10, 0x00000081 );
mtdcr( 0x11, 0x80000800 );
/* MCIF0_SDTR1 */
mtdcr( 0x10, 0x00000085 );
mtdcr( 0x11, 0x80201000 );
/* MCIF0_SDTR2 */
mtdcr( 0x10, 0x00000086 );
mtdcr( 0x11, 0x42103242 );
/* MCIF0_SDTR3 */
mtdcr( 0x10, 0x00000087 );
mtdcr( 0x11, 0x0C100D14 );
/* SET MQ0_B0BAS base addr 00000000 / 256MB */
mtdcr( 0x40, 0x0000F800 );
/* SET MQ0_B1BAS base addr 10000000 / 256MB */
mtdcr( 0x41, 0x0400F800 );
/* SET MQ0_B2BAS base addr 20000000 / 256MB */
if (yucca_dimms == 2)
mtdcr( 0x42, 0x0800F800 );
else if (yucca_dimms == 1)
mtdcr( 0x42, 0x00000000 );
/* SET MQ0_B3BAS base addr 30000000 / 256MB */
if (yucca_dimms == 2)
mtdcr( 0x43, 0x0C00F800 );
else if (yucca_dimms == 1)
mtdcr( 0x43, 0x00000000 );
/* SDRAM_RQDC */
mtdcr( 0x10, 0x00000070 );
mtdcr( 0x11, 0x8000003F );
/* SDRAM_RDCC */
mtdcr( 0x10, 0x00000078 );
mtdcr( 0x11, 0x80000000 );
/* SDRAM_RFDC */
mtdcr( 0x10, 0x00000074 );
mtdcr( 0x11, 0x00000220 );
return (yucca_dimms * 512) << 20;
}
long int initdram (int board_type)
{
long dram_size = 0;
dram_size = fixed_sdram();
return dram_size;
}
#if defined(CFG_DRAM_TEST)
int testdram (void)
{
@ -1267,42 +994,3 @@ int onboard_pci_arbiter_selected(int core_pci)
#endif
return (BOARD_OPTION_NOT_SELECTED);
}
/*---------------------------------------------------------------------------+
| ppcMfcpr.
+---------------------------------------------------------------------------*/
unsigned long ppcMfcpr(unsigned long cpr_reg)
{
unsigned long msr;
unsigned long cpr_cfgaddr_temp;
unsigned long cpr_value;
msr = (mfmsr () & ~(MSR_EE));
cpr_cfgaddr_temp = mfdcr(CPR0_CFGADDR);
mtdcr(CPR0_CFGADDR, cpr_reg);
cpr_value = mfdcr(CPR0_CFGDATA);
mtdcr(CPR0_CFGADDR, cpr_cfgaddr_temp);
mtmsr(msr);
return (cpr_value);
}
/*----------------------------------------------------------------------------+
| Indirect Access of the System DCR's (SDR)
| ppcMfsdr
+----------------------------------------------------------------------------*/
unsigned long ppcMfsdr(unsigned long sdr_reg)
{
unsigned long msr;
unsigned long sdr_cfgaddr_temp;
unsigned long sdr_value;
msr = (mfmsr () & ~(MSR_EE));
sdr_cfgaddr_temp = mfdcr(SDR0_CFGADDR);
mtdcr(SDR0_CFGADDR, sdr_reg);
sdr_value = mfdcr(SDR0_CFGDATA);
mtdcr(SDR0_CFGADDR, sdr_cfgaddr_temp);
mtmsr(msr);
return (sdr_value);
}

View file

@ -45,11 +45,11 @@
#define EXTCLK_50 50000000
#define EXTCLK_83 83333333
#define CONFIG_IBM_EMAC4_V4 1
#define CONFIG_MISC_INIT_F 1 /* Use misc_init_f() */
#define CONFIG_MISC_INIT_F 1 /* Use misc_init_f() */
#define CONFIG_ADD_RAM_INFO 1 /* Print additional info */
#undef CONFIG_SHOW_BOOT_PROGRESS
#undef CONFIG_STRESS
#undef ENABLE_ECC
/*-----------------------------------------------------------------------
* Base addresses -- Note these are effective addresses where the
* actual resources get mapped (not physical addresses)
@ -118,10 +118,9 @@
/*-----------------------------------------------------------------------
* DDR SDRAM
*----------------------------------------------------------------------*/
#undef CONFIG_SPD_EEPROM /* Use SPD EEPROM for setup */
#define SPD_EEPROM_ADDRESS {0x53, 0x52} /* SPD i2c spd addresses */
#define IIC0_DIMM0_ADDR 0x53
#define IIC0_DIMM1_ADDR 0x52
#define CONFIG_SPD_EEPROM 1 /* Use SPD EEPROM for setup */
#define SPD_EEPROM_ADDRESS {0x53, 0x52} /* SPD i2c spd addresses*/
#undef CONFIG_DDR_ECC /* no ECC support for now */
/*-----------------------------------------------------------------------
* I2C
@ -211,6 +210,7 @@
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
#define CONFIG_IBM_EMAC4_V4 1
#define CONFIG_MII 1 /* MII PHY management */
#undef CONFIG_NET_MULTI
#define CONFIG_PHY_ADDR 1 /* PHY address, See schematics */