mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-20 08:58:52 +09:00
![Stefan Roese](/assets/img/avatar_default.png)
The latest PPC4xx register cleanup patch missed some SDRAM defines. This patch now changes lower case UIC defines to upper case. Also some names are changed to match the naming in the IBM/AMCC users manuals (e.g. mem_mcopt1 -> SDRAM0_CFG). Signed-off-by: Stefan Roese <sr@denx.de>
956 lines
24 KiB
C
956 lines
24 KiB
C
/*
|
|
* (C) Copyright 2001
|
|
* Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
|
|
*
|
|
* 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
|
|
*
|
|
*
|
|
* TODO: clean-up
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include "pip405.h"
|
|
#include <asm/processor.h>
|
|
#include <i2c.h>
|
|
#include <stdio_dev.h>
|
|
#include "../common/isa.h"
|
|
#include "../common/common_util.h"
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
#undef SDRAM_DEBUG
|
|
|
|
#define FALSE 0
|
|
#define TRUE 1
|
|
|
|
/* stdlib.h causes some compatibility problems; should fixe these! -- wd */
|
|
#ifndef __ldiv_t_defined
|
|
typedef struct {
|
|
long int quot; /* Quotient */
|
|
long int rem; /* Remainder */
|
|
} ldiv_t;
|
|
extern ldiv_t ldiv (long int __numer, long int __denom);
|
|
|
|
# define __ldiv_t_defined 1
|
|
#endif
|
|
|
|
|
|
typedef enum {
|
|
SDRAM_NO_ERR,
|
|
SDRAM_SPD_COMM_ERR,
|
|
SDRAM_SPD_CHKSUM_ERR,
|
|
SDRAM_UNSUPPORTED_ERR,
|
|
SDRAM_UNKNOWN_ERR
|
|
} SDRAM_ERR;
|
|
|
|
typedef struct {
|
|
const unsigned char mode;
|
|
const unsigned char row;
|
|
const unsigned char col;
|
|
const unsigned char bank;
|
|
} SDRAM_SETUP;
|
|
|
|
static const SDRAM_SETUP sdram_setup_table[] = {
|
|
{1, 11, 9, 2},
|
|
{1, 11, 10, 2},
|
|
{2, 12, 9, 4},
|
|
{2, 12, 10, 4},
|
|
{3, 13, 9, 4},
|
|
{3, 13, 10, 4},
|
|
{3, 13, 11, 4},
|
|
{4, 12, 8, 2},
|
|
{4, 12, 8, 4},
|
|
{5, 11, 8, 2},
|
|
{5, 11, 8, 4},
|
|
{6, 13, 8, 2},
|
|
{6, 13, 8, 4},
|
|
{7, 13, 9, 2},
|
|
{7, 13, 10, 2},
|
|
{0, 0, 0, 0}
|
|
};
|
|
|
|
static const unsigned char cal_indextable[] = {
|
|
9, 23, 25
|
|
};
|
|
|
|
|
|
/*
|
|
* translate ns.ns/10 coding of SPD timing values
|
|
* into 10 ps unit values
|
|
*/
|
|
|
|
unsigned short NS10to10PS (unsigned char spd_byte, unsigned char spd_version)
|
|
{
|
|
unsigned short ns, ns10;
|
|
|
|
/* isolate upper nibble */
|
|
ns = (spd_byte >> 4) & 0x0F;
|
|
/* isolate lower nibble */
|
|
ns10 = (spd_byte & 0x0F);
|
|
|
|
return (ns * 100 + ns10 * 10);
|
|
}
|
|
|
|
/*
|
|
* translate ns.ns/4 coding of SPD timing values
|
|
* into 10 ps unit values
|
|
*/
|
|
|
|
unsigned short NS4to10PS (unsigned char spd_byte, unsigned char spd_version)
|
|
{
|
|
unsigned short ns, ns4;
|
|
|
|
/* isolate upper 6 bits */
|
|
ns = (spd_byte >> 2) & 0x3F;
|
|
/* isloate lower 2 bits */
|
|
ns4 = (spd_byte & 0x03);
|
|
|
|
return (ns * 100 + ns4 * 25);
|
|
}
|
|
|
|
/*
|
|
* translate ns coding of SPD timing values
|
|
* into 10 ps unit values
|
|
*/
|
|
|
|
unsigned short NSto10PS (unsigned char spd_byte)
|
|
{
|
|
return (spd_byte * 100);
|
|
}
|
|
|
|
void SDRAM_err (const char *s)
|
|
{
|
|
#ifndef SDRAM_DEBUG
|
|
(void) get_clocks ();
|
|
gd->baudrate = 9600;
|
|
serial_init ();
|
|
#endif
|
|
serial_puts ("\n");
|
|
serial_puts (s);
|
|
serial_puts ("\n enable SDRAM_DEBUG for more info\n");
|
|
for (;;);
|
|
}
|
|
|
|
|
|
#ifdef SDRAM_DEBUG
|
|
|
|
void write_hex (unsigned char i)
|
|
{
|
|
char cc;
|
|
|
|
cc = i >> 4;
|
|
cc &= 0xf;
|
|
if (cc > 9)
|
|
serial_putc (cc + 55);
|
|
else
|
|
serial_putc (cc + 48);
|
|
cc = i & 0xf;
|
|
if (cc > 9)
|
|
serial_putc (cc + 55);
|
|
else
|
|
serial_putc (cc + 48);
|
|
}
|
|
|
|
void write_4hex (unsigned long val)
|
|
{
|
|
write_hex ((unsigned char) (val >> 24));
|
|
write_hex ((unsigned char) (val >> 16));
|
|
write_hex ((unsigned char) (val >> 8));
|
|
write_hex ((unsigned char) val);
|
|
}
|
|
|
|
#endif
|
|
|
|
int board_early_init_f (void)
|
|
{
|
|
unsigned char dataout[1];
|
|
unsigned char datain[128];
|
|
unsigned long sdram_size = 0;
|
|
SDRAM_SETUP *t = (SDRAM_SETUP *) sdram_setup_table;
|
|
unsigned long memclk;
|
|
unsigned long tmemclk = 0;
|
|
unsigned long tmp, bank, baseaddr, bank_size;
|
|
unsigned short i;
|
|
unsigned char rows, cols, banks, sdram_banks, density;
|
|
unsigned char supported_cal, trp_clocks, trcd_clocks, tras_clocks,
|
|
trc_clocks, tctp_clocks;
|
|
unsigned char cal_index, cal_val, spd_version, spd_chksum;
|
|
unsigned char buf[8];
|
|
/* set up the config port */
|
|
mtdcr (EBC0_CFGADDR, PB7AP);
|
|
mtdcr (EBC0_CFGDATA, CONFIG_PORT_AP);
|
|
mtdcr (EBC0_CFGADDR, PB7CR);
|
|
mtdcr (EBC0_CFGDATA, CONFIG_PORT_CR);
|
|
|
|
memclk = get_bus_freq (tmemclk);
|
|
tmemclk = 1000000000 / (memclk / 100); /* in 10 ps units */
|
|
|
|
#ifdef SDRAM_DEBUG
|
|
(void) get_clocks ();
|
|
gd->baudrate = 9600;
|
|
serial_init ();
|
|
serial_puts ("\nstart SDRAM Setup\n");
|
|
#endif
|
|
|
|
/* Read Serial Presence Detect Information */
|
|
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
|
|
dataout[0] = 0;
|
|
for (i = 0; i < 128; i++)
|
|
datain[i] = 127;
|
|
i2c_read(SPD_EEPROM_ADDRESS,0,1,datain,128);
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts ("\ni2c_read returns ");
|
|
write_hex (i);
|
|
serial_puts ("\n");
|
|
#endif
|
|
|
|
#ifdef SDRAM_DEBUG
|
|
for (i = 0; i < 128; i++) {
|
|
write_hex (datain[i]);
|
|
serial_puts (" ");
|
|
if (((i + 1) % 16) == 0)
|
|
serial_puts ("\n");
|
|
}
|
|
serial_puts ("\n");
|
|
#endif
|
|
spd_chksum = 0;
|
|
for (i = 0; i < 63; i++) {
|
|
spd_chksum += datain[i];
|
|
} /* endfor */
|
|
if (datain[63] != spd_chksum) {
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts ("SPD chksum: 0x");
|
|
write_hex (datain[63]);
|
|
serial_puts (" != calc. chksum: 0x");
|
|
write_hex (spd_chksum);
|
|
serial_puts ("\n");
|
|
#endif
|
|
SDRAM_err ("SPD checksum Error");
|
|
}
|
|
/* SPD seems to be ok, use it */
|
|
|
|
/* get SPD version */
|
|
spd_version = datain[62];
|
|
|
|
/* do some sanity checks on the kind of RAM */
|
|
if ((datain[0] < 0x80) || /* less than 128 valid bytes in SPD */
|
|
(datain[2] != 0x04) || /* if not SDRAM */
|
|
(!((datain[6] == 0x40) || (datain[6] == 0x48))) || /* or not (64 Bit or 72 Bit) */
|
|
(datain[7] != 0x00) || (datain[8] != 0x01) || /* or not LVTTL signal levels */
|
|
(datain[126] == 0x66)) /* or a 66MHz modules */
|
|
SDRAM_err ("unsupported SDRAM");
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts ("SDRAM sanity ok\n");
|
|
#endif
|
|
|
|
/* get number of rows/cols/banks out of byte 3+4+5 */
|
|
rows = datain[3];
|
|
cols = datain[4];
|
|
banks = datain[5];
|
|
|
|
/* get number of SDRAM banks out of byte 17 and
|
|
supported CAS latencies out of byte 18 */
|
|
sdram_banks = datain[17];
|
|
supported_cal = datain[18] & ~0x81;
|
|
|
|
while (t->mode != 0) {
|
|
if ((t->row == rows) && (t->col == cols)
|
|
&& (t->bank == sdram_banks))
|
|
break;
|
|
t++;
|
|
} /* endwhile */
|
|
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts ("rows: ");
|
|
write_hex (rows);
|
|
serial_puts (" cols: ");
|
|
write_hex (cols);
|
|
serial_puts (" banks: ");
|
|
write_hex (banks);
|
|
serial_puts (" mode: ");
|
|
write_hex (t->mode);
|
|
serial_puts ("\n");
|
|
#endif
|
|
if (t->mode == 0)
|
|
SDRAM_err ("unsupported SDRAM");
|
|
/* get tRP, tRCD, tRAS and density from byte 27+29+30+31 */
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts ("tRP: ");
|
|
write_hex (datain[27]);
|
|
serial_puts ("\ntRCD: ");
|
|
write_hex (datain[29]);
|
|
serial_puts ("\ntRAS: ");
|
|
write_hex (datain[30]);
|
|
serial_puts ("\n");
|
|
#endif
|
|
|
|
trp_clocks = (NSto10PS (datain[27]) + (tmemclk - 1)) / tmemclk;
|
|
trcd_clocks = (NSto10PS (datain[29]) + (tmemclk - 1)) / tmemclk;
|
|
tras_clocks = (NSto10PS (datain[30]) + (tmemclk - 1)) / tmemclk;
|
|
density = datain[31];
|
|
|
|
/* trc_clocks is sum of trp_clocks + tras_clocks */
|
|
trc_clocks = trp_clocks + tras_clocks;
|
|
/* ctp = ((trp + tras) - trp - trcd) => tras - trcd */
|
|
tctp_clocks =
|
|
((NSto10PS (datain[30]) - NSto10PS (datain[29])) +
|
|
(tmemclk - 1)) / tmemclk;
|
|
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts ("c_RP: ");
|
|
write_hex (trp_clocks);
|
|
serial_puts ("\nc_RCD: ");
|
|
write_hex (trcd_clocks);
|
|
serial_puts ("\nc_RAS: ");
|
|
write_hex (tras_clocks);
|
|
serial_puts ("\nc_RC: (RP+RAS): ");
|
|
write_hex (trc_clocks);
|
|
serial_puts ("\nc_CTP: ((RP+RAS)-RP-RCD): ");
|
|
write_hex (tctp_clocks);
|
|
serial_puts ("\nt_CTP: RAS - RCD: ");
|
|
write_hex ((unsigned
|
|
char) ((NSto10PS (datain[30]) -
|
|
NSto10PS (datain[29])) >> 8));
|
|
write_hex ((unsigned char) (NSto10PS (datain[30]) - NSto10PS (datain[29])));
|
|
serial_puts ("\ntmemclk: ");
|
|
write_hex ((unsigned char) (tmemclk >> 8));
|
|
write_hex ((unsigned char) (tmemclk));
|
|
serial_puts ("\n");
|
|
#endif
|
|
|
|
|
|
cal_val = 255;
|
|
for (i = 6, cal_index = 0; (i > 0) && (cal_index < 3); i--) {
|
|
/* is this CAS latency supported ? */
|
|
if ((supported_cal >> i) & 0x01) {
|
|
buf[0] = datain[cal_indextable[cal_index]];
|
|
if (cal_index < 2) {
|
|
if (NS10to10PS (buf[0], spd_version) <= tmemclk)
|
|
cal_val = i;
|
|
} else {
|
|
/* SPD bytes 25+26 have another format */
|
|
if (NS4to10PS (buf[0], spd_version) <= tmemclk)
|
|
cal_val = i;
|
|
} /* endif */
|
|
cal_index++;
|
|
} /* endif */
|
|
} /* endfor */
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts ("CAL: ");
|
|
write_hex (cal_val + 1);
|
|
serial_puts ("\n");
|
|
#endif
|
|
|
|
if (cal_val == 255)
|
|
SDRAM_err ("unsupported SDRAM");
|
|
|
|
/* get SDRAM timing register */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_TR);
|
|
tmp = mfdcr (SDRAM0_CFGDATA) & ~0x018FC01F;
|
|
/* insert CASL value */
|
|
/* tmp |= ((unsigned long)cal_val) << 23; */
|
|
tmp |= ((unsigned long) cal_val) << 23;
|
|
/* insert PTA value */
|
|
tmp |= ((unsigned long) (trp_clocks - 1)) << 18;
|
|
/* insert CTP value */
|
|
/* tmp |= ((unsigned long)(trc_clocks - trp_clocks - trcd_clocks - 1)) << 16; */
|
|
tmp |= ((unsigned long) (trc_clocks - trp_clocks - trcd_clocks)) << 16;
|
|
/* insert LDF (always 01) */
|
|
tmp |= ((unsigned long) 0x01) << 14;
|
|
/* insert RFTA value */
|
|
tmp |= ((unsigned long) (trc_clocks - 4)) << 2;
|
|
/* insert RCD value */
|
|
tmp |= ((unsigned long) (trcd_clocks - 1)) << 0;
|
|
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts ("sdtr: ");
|
|
write_4hex (tmp);
|
|
serial_puts ("\n");
|
|
#endif
|
|
|
|
/* write SDRAM timing register */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_TR);
|
|
mtdcr (SDRAM0_CFGDATA, tmp);
|
|
baseaddr = CONFIG_SYS_SDRAM_BASE;
|
|
bank_size = (((unsigned long) density) << 22) / 2;
|
|
/* insert AM value */
|
|
tmp = ((unsigned long) t->mode - 1) << 13;
|
|
/* insert SZ value; */
|
|
switch (bank_size) {
|
|
case 0x00400000:
|
|
tmp |= ((unsigned long) 0x00) << 17;
|
|
break;
|
|
case 0x00800000:
|
|
tmp |= ((unsigned long) 0x01) << 17;
|
|
break;
|
|
case 0x01000000:
|
|
tmp |= ((unsigned long) 0x02) << 17;
|
|
break;
|
|
case 0x02000000:
|
|
tmp |= ((unsigned long) 0x03) << 17;
|
|
break;
|
|
case 0x04000000:
|
|
tmp |= ((unsigned long) 0x04) << 17;
|
|
break;
|
|
case 0x08000000:
|
|
tmp |= ((unsigned long) 0x05) << 17;
|
|
break;
|
|
case 0x10000000:
|
|
tmp |= ((unsigned long) 0x06) << 17;
|
|
break;
|
|
default:
|
|
SDRAM_err ("unsupported SDRAM");
|
|
} /* endswitch */
|
|
/* get SDRAM bank 0 register */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
|
|
bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
|
|
bank |= (baseaddr | tmp | 0x01);
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts ("bank0: baseaddr: ");
|
|
write_4hex (baseaddr);
|
|
serial_puts (" banksize: ");
|
|
write_4hex (bank_size);
|
|
serial_puts (" mb0cf: ");
|
|
write_4hex (bank);
|
|
serial_puts ("\n");
|
|
#endif
|
|
baseaddr += bank_size;
|
|
sdram_size += bank_size;
|
|
|
|
/* write SDRAM bank 0 register */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
|
|
mtdcr (SDRAM0_CFGDATA, bank);
|
|
|
|
/* get SDRAM bank 1 register */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR);
|
|
bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
|
|
sdram_size = 0;
|
|
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts ("bank1: baseaddr: ");
|
|
write_4hex (baseaddr);
|
|
serial_puts (" banksize: ");
|
|
write_4hex (bank_size);
|
|
#endif
|
|
if (banks == 2) {
|
|
bank |= (baseaddr | tmp | 0x01);
|
|
baseaddr += bank_size;
|
|
sdram_size += bank_size;
|
|
} /* endif */
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts (" mb1cf: ");
|
|
write_4hex (bank);
|
|
serial_puts ("\n");
|
|
#endif
|
|
/* write SDRAM bank 1 register */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR);
|
|
mtdcr (SDRAM0_CFGDATA, bank);
|
|
|
|
/* get SDRAM bank 2 register */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR);
|
|
bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
|
|
|
|
bank |= (baseaddr | tmp | 0x01);
|
|
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts ("bank2: baseaddr: ");
|
|
write_4hex (baseaddr);
|
|
serial_puts (" banksize: ");
|
|
write_4hex (bank_size);
|
|
serial_puts (" mb2cf: ");
|
|
write_4hex (bank);
|
|
serial_puts ("\n");
|
|
#endif
|
|
|
|
baseaddr += bank_size;
|
|
sdram_size += bank_size;
|
|
|
|
/* write SDRAM bank 2 register */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR);
|
|
mtdcr (SDRAM0_CFGDATA, bank);
|
|
|
|
/* get SDRAM bank 3 register */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR);
|
|
bank = mfdcr (SDRAM0_CFGDATA) & ~0xFFCEE001;
|
|
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts ("bank3: baseaddr: ");
|
|
write_4hex (baseaddr);
|
|
serial_puts (" banksize: ");
|
|
write_4hex (bank_size);
|
|
#endif
|
|
|
|
if (banks == 2) {
|
|
bank |= (baseaddr | tmp | 0x01);
|
|
baseaddr += bank_size;
|
|
sdram_size += bank_size;
|
|
}
|
|
/* endif */
|
|
#ifdef SDRAM_DEBUG
|
|
serial_puts (" mb3cf: ");
|
|
write_4hex (bank);
|
|
serial_puts ("\n");
|
|
#endif
|
|
|
|
/* write SDRAM bank 3 register */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR);
|
|
mtdcr (SDRAM0_CFGDATA, bank);
|
|
|
|
|
|
/* get SDRAM refresh interval register */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR);
|
|
tmp = mfdcr (SDRAM0_CFGDATA) & ~0x3FF80000;
|
|
|
|
if (tmemclk < NSto10PS (16))
|
|
tmp |= 0x05F00000;
|
|
else
|
|
tmp |= 0x03F80000;
|
|
|
|
/* write SDRAM refresh interval register */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_RTR);
|
|
mtdcr (SDRAM0_CFGDATA, tmp);
|
|
|
|
/* enable SDRAM controller with no ECC, 32-bit SDRAM width, 16 byte burst */
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
|
|
tmp = (mfdcr (SDRAM0_CFGDATA) & ~0xFFE00000) | 0x80E00000;
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_CFG);
|
|
mtdcr (SDRAM0_CFGDATA, tmp);
|
|
|
|
|
|
/*-------------------------------------------------------------------------+
|
|
| Interrupt controller setup for the PIP405 board.
|
|
| Note: IRQ 0-15 405GP internally generated; active high; level sensitive
|
|
| IRQ 16 405GP internally generated; active low; level sensitive
|
|
| IRQ 17-24 RESERVED
|
|
| IRQ 25 (EXT IRQ 0) SouthBridg; active low; level sensitive
|
|
| IRQ 26 (EXT IRQ 1) NMI: active low; level sensitive
|
|
| IRQ 27 (EXT IRQ 2) SMI: active Low; level sensitive
|
|
| IRQ 28 (EXT IRQ 3) PCI SLOT 3; active low; level sensitive
|
|
| IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
|
|
| IRQ 30 (EXT IRQ 5) PCI SLOT 1; active low; level sensitive
|
|
| IRQ 31 (EXT IRQ 6) PCI SLOT 0; active low; level sensitive
|
|
| Note for PIP405 board:
|
|
| An interrupt taken for the SouthBridge (IRQ 25) indicates that
|
|
| the Interrupt Controller in the South Bridge has caused the
|
|
| interrupt. The IC must be read to determine which device
|
|
| caused the interrupt.
|
|
|
|
|
+-------------------------------------------------------------------------*/
|
|
mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */
|
|
mtdcr (UIC0ER, 0x00000000); /* disable all ints */
|
|
mtdcr (UIC0CR, 0x00000000); /* set all to be non-critical (for now) */
|
|
mtdcr (UIC0PR, 0xFFFFFF80); /* set int polarities */
|
|
mtdcr (UIC0TR, 0x10000000); /* set int trigger levels */
|
|
mtdcr (UIC0VCR, 0x00000001); /* set vect base=0,INT0 highest priority */
|
|
mtdcr (UIC0SR, 0xFFFFFFFF); /* clear all ints */
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/*
|
|
* Check Board Identity:
|
|
*/
|
|
|
|
int checkboard (void)
|
|
{
|
|
char s[50];
|
|
unsigned char bc;
|
|
int i;
|
|
backup_t *b = (backup_t *) s;
|
|
|
|
puts ("Board: ");
|
|
|
|
i = getenv_r ("serial#", (char *)s, 32);
|
|
if ((i == 0) || strncmp ((char *)s, "PIP405", 6)) {
|
|
get_backup_values (b);
|
|
if (strncmp (b->signature, "MPL\0", 4) != 0) {
|
|
puts ("### No HW ID - assuming PIP405");
|
|
} else {
|
|
b->serial_name[6] = 0;
|
|
printf ("%s SN: %s", b->serial_name,
|
|
&b->serial_name[7]);
|
|
}
|
|
} else {
|
|
s[6] = 0;
|
|
printf ("%s SN: %s", s, &s[7]);
|
|
}
|
|
bc = in8 (CONFIG_PORT_ADDR);
|
|
printf (" Boot Config: 0x%x\n", bc);
|
|
return (0);
|
|
}
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* ------------------------------------------------------------------------- */
|
|
/*
|
|
initdram(int board_type) reads EEPROM via I2c. EEPROM contains all of
|
|
the necessary info for SDRAM controller configuration
|
|
*/
|
|
/* ------------------------------------------------------------------------- */
|
|
/* ------------------------------------------------------------------------- */
|
|
static int test_dram (unsigned long ramsize);
|
|
|
|
phys_size_t initdram (int board_type)
|
|
{
|
|
unsigned long bank_reg[4], tmp, bank_size;
|
|
int i, ds;
|
|
unsigned long TotalSize;
|
|
|
|
ds = 0;
|
|
/* since the DRAM controller is allready set up,
|
|
* calculate the size with the bank registers
|
|
*/
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_B0CR);
|
|
bank_reg[0] = mfdcr (SDRAM0_CFGDATA);
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_B1CR);
|
|
bank_reg[1] = mfdcr (SDRAM0_CFGDATA);
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_B2CR);
|
|
bank_reg[2] = mfdcr (SDRAM0_CFGDATA);
|
|
mtdcr (SDRAM0_CFGADDR, SDRAM0_B3CR);
|
|
bank_reg[3] = mfdcr (SDRAM0_CFGDATA);
|
|
TotalSize = 0;
|
|
for (i = 0; i < 4; i++) {
|
|
if ((bank_reg[i] & 0x1) == 0x1) {
|
|
tmp = (bank_reg[i] >> 17) & 0x7;
|
|
bank_size = 4 << tmp;
|
|
TotalSize += bank_size;
|
|
} else
|
|
ds = 1;
|
|
}
|
|
if (ds == 1)
|
|
printf ("single-sided DIMM ");
|
|
else
|
|
printf ("double-sided DIMM ");
|
|
test_dram (TotalSize * 1024 * 1024);
|
|
/* bank 2 (SDRAM Clock 2) is not usable if 133MHz SDRAM IF */
|
|
(void) get_clocks();
|
|
if (gd->cpu_clk > 220000000)
|
|
TotalSize /= 2;
|
|
return (TotalSize * 1024 * 1024);
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
|
|
static int test_dram (unsigned long ramsize)
|
|
{
|
|
/* not yet implemented */
|
|
return (1);
|
|
}
|
|
|
|
|
|
extern flash_info_t flash_info[]; /* info for FLASH chips */
|
|
|
|
int misc_init_r (void)
|
|
{
|
|
/* adjust flash start and size as well as the offset */
|
|
gd->bd->bi_flashstart=0-flash_info[0].size;
|
|
gd->bd->bi_flashsize=flash_info[0].size-CONFIG_SYS_MONITOR_LEN;
|
|
gd->bd->bi_flashoffset=0;
|
|
|
|
/* if PIP405 has booted from PCI, reset CCR0[24] as described in errata PCI_18 */
|
|
if (mfdcr(CPC0_PSR) & PSR_ROM_LOC)
|
|
mtspr(SPRN_CCR0, (mfspr(SPRN_CCR0) & ~0x80));
|
|
|
|
return (0);
|
|
}
|
|
|
|
/***************************************************************************
|
|
* some helping routines
|
|
*/
|
|
|
|
int overwrite_console (void)
|
|
{
|
|
return (in8 (CONFIG_PORT_ADDR) & 0x1); /* return TRUE if console should be overwritten */
|
|
}
|
|
|
|
|
|
extern int isa_init (void);
|
|
|
|
|
|
void print_pip405_rev (void)
|
|
{
|
|
unsigned char part, vers, cfg;
|
|
|
|
part = in8 (PLD_PART_REG);
|
|
vers = in8 (PLD_VERS_REG);
|
|
cfg = in8 (PLD_BOARD_CFG_REG);
|
|
printf ("Rev: PIP405-%d Rev %c PLD%d %d PLD%d %d\n",
|
|
16 - ((cfg >> 4) & 0xf), (cfg & 0xf) + 'A', part & 0xf,
|
|
vers & 0xf, (part >> 4) & 0xf, (vers >> 4) & 0xf);
|
|
}
|
|
|
|
extern void check_env(void);
|
|
|
|
|
|
int last_stage_init (void)
|
|
{
|
|
print_pip405_rev ();
|
|
isa_init ();
|
|
stdio_print_current_devices ();
|
|
check_env();
|
|
return 0;
|
|
}
|
|
|
|
/************************************************************************
|
|
* Print PIP405 Info
|
|
************************************************************************/
|
|
void print_pip405_info (void)
|
|
{
|
|
unsigned char part, vers, cfg, ledu, sysman, flashcom, can, serpwr,
|
|
compwr, nicvga, scsirst;
|
|
|
|
part = in8 (PLD_PART_REG);
|
|
vers = in8 (PLD_VERS_REG);
|
|
cfg = in8 (PLD_BOARD_CFG_REG);
|
|
ledu = in8 (PLD_LED_USER_REG);
|
|
sysman = in8 (PLD_SYS_MAN_REG);
|
|
flashcom = in8 (PLD_FLASH_COM_REG);
|
|
can = in8 (PLD_CAN_REG);
|
|
serpwr = in8 (PLD_SER_PWR_REG);
|
|
compwr = in8 (PLD_COM_PWR_REG);
|
|
nicvga = in8 (PLD_NIC_VGA_REG);
|
|
scsirst = in8 (PLD_SCSI_RST_REG);
|
|
printf ("PLD Part %d version %d\n",
|
|
part & 0xf, vers & 0xf);
|
|
printf ("PLD Part %d version %d\n",
|
|
(part >> 4) & 0xf, (vers >> 4) & 0xf);
|
|
printf ("Board Revision %c\n", (cfg & 0xf) + 'A');
|
|
printf ("Population Options %d %d %d %d\n",
|
|
(cfg >> 4) & 0x1, (cfg >> 5) & 0x1,
|
|
(cfg >> 6) & 0x1, (cfg >> 7) & 0x1);
|
|
printf ("User LED0 %s User LED1 %s\n",
|
|
((ledu & 0x1) == 0x1) ? "on" : "off",
|
|
((ledu & 0x2) == 0x2) ? "on" : "off");
|
|
printf ("Additionally Options %d %d\n",
|
|
(ledu >> 2) & 0x1, (ledu >> 3) & 0x1);
|
|
printf ("User Config Switch %d %d %d %d\n",
|
|
(ledu >> 4) & 0x1, (ledu >> 5) & 0x1,
|
|
(ledu >> 6) & 0x1, (ledu >> 7) & 0x1);
|
|
switch (sysman & 0x3) {
|
|
case 0:
|
|
printf ("PCI Clocks are running\n");
|
|
break;
|
|
case 1:
|
|
printf ("PCI Clocks are stopped in POS State\n");
|
|
break;
|
|
case 2:
|
|
printf ("PCI Clocks are stopped when PCI_STP# is asserted\n");
|
|
break;
|
|
case 3:
|
|
printf ("PCI Clocks are stopped\n");
|
|
break;
|
|
}
|
|
switch ((sysman >> 2) & 0x3) {
|
|
case 0:
|
|
printf ("Main Clocks are running\n");
|
|
break;
|
|
case 1:
|
|
printf ("Main Clocks are stopped in POS State\n");
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
printf ("PCI Clocks are stopped\n");
|
|
break;
|
|
}
|
|
printf ("INIT asserts %sINT2# (SMI)\n",
|
|
((sysman & 0x10) == 0x10) ? "" : "not ");
|
|
printf ("INIT asserts %sINT1# (NMI)\n",
|
|
((sysman & 0x20) == 0x20) ? "" : "not ");
|
|
printf ("INIT occured %d\n", (sysman >> 6) & 0x1);
|
|
printf ("SER1 is routed to %s\n",
|
|
((flashcom & 0x1) == 0x1) ? "RS485" : "RS232");
|
|
printf ("COM2 is routed to %s\n",
|
|
((flashcom & 0x2) == 0x2) ? "RS485" : "RS232");
|
|
printf ("RS485 is configured as %s duplex\n",
|
|
((flashcom & 0x4) == 0x4) ? "full" : "half");
|
|
printf ("RS485 is connected to %s\n",
|
|
((flashcom & 0x8) == 0x8) ? "COM1" : "COM2");
|
|
printf ("SER1 uses handshakes %s\n",
|
|
((flashcom & 0x10) == 0x10) ? "DTR/DSR" : "RTS/CTS");
|
|
printf ("Bootflash is %swriteprotected\n",
|
|
((flashcom & 0x20) == 0x20) ? "not " : "");
|
|
printf ("Bootflash VPP is %s\n",
|
|
((flashcom & 0x40) == 0x40) ? "on" : "off");
|
|
printf ("Bootsector is %swriteprotected\n",
|
|
((flashcom & 0x80) == 0x80) ? "not " : "");
|
|
switch ((can) & 0x3) {
|
|
case 0:
|
|
printf ("CAN Controller is on address 0x1000..0x10FF\n");
|
|
break;
|
|
case 1:
|
|
printf ("CAN Controller is on address 0x8000..0x80FF\n");
|
|
break;
|
|
case 2:
|
|
printf ("CAN Controller is on address 0xE000..0xE0FF\n");
|
|
break;
|
|
case 3:
|
|
printf ("CAN Controller is disabled\n");
|
|
break;
|
|
}
|
|
switch ((can >> 2) & 0x3) {
|
|
case 0:
|
|
printf ("CAN Controller Reset is ISA Reset\n");
|
|
break;
|
|
case 1:
|
|
printf ("CAN Controller Reset is ISA Reset and POS State\n");
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
printf ("CAN Controller is in reset\n");
|
|
break;
|
|
}
|
|
if (((can >> 4) < 3) || ((can >> 4) == 8) || ((can >> 4) == 13))
|
|
printf ("CAN Interrupt is disabled\n");
|
|
else
|
|
printf ("CAN Interrupt is ISA INT%d\n", (can >> 4) & 0xf);
|
|
switch (serpwr & 0x3) {
|
|
case 0:
|
|
printf ("SER0 Drivers are enabled\n");
|
|
break;
|
|
case 1:
|
|
printf ("SER0 Drivers are disabled in the POS state\n");
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
printf ("SER0 Drivers are disabled\n");
|
|
break;
|
|
}
|
|
switch ((serpwr >> 2) & 0x3) {
|
|
case 0:
|
|
printf ("SER1 Drivers are enabled\n");
|
|
break;
|
|
case 1:
|
|
printf ("SER1 Drivers are disabled in the POS state\n");
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
printf ("SER1 Drivers are disabled\n");
|
|
break;
|
|
}
|
|
switch (compwr & 0x3) {
|
|
case 0:
|
|
printf ("COM1 Drivers are enabled\n");
|
|
break;
|
|
case 1:
|
|
printf ("COM1 Drivers are disabled in the POS state\n");
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
printf ("COM1 Drivers are disabled\n");
|
|
break;
|
|
}
|
|
switch ((compwr >> 2) & 0x3) {
|
|
case 0:
|
|
printf ("COM2 Drivers are enabled\n");
|
|
break;
|
|
case 1:
|
|
printf ("COM2 Drivers are disabled in the POS state\n");
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
printf ("COM2 Drivers are disabled\n");
|
|
break;
|
|
}
|
|
switch ((nicvga) & 0x3) {
|
|
case 0:
|
|
printf ("PHY is running\n");
|
|
break;
|
|
case 1:
|
|
printf ("PHY is in Power save mode in POS state\n");
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
printf ("PHY is in Power save mode\n");
|
|
break;
|
|
}
|
|
switch ((nicvga >> 2) & 0x3) {
|
|
case 0:
|
|
printf ("VGA is running\n");
|
|
break;
|
|
case 1:
|
|
printf ("VGA is in Power save mode in POS state\n");
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
printf ("VGA is in Power save mode\n");
|
|
break;
|
|
}
|
|
printf ("PHY is %sreseted\n", ((nicvga & 0x10) == 0x10) ? "" : "not ");
|
|
printf ("VGA is %sreseted\n", ((nicvga & 0x20) == 0x20) ? "" : "not ");
|
|
printf ("Reserved Configuration is %d %d\n", (nicvga >> 6) & 0x1,
|
|
(nicvga >> 7) & 0x1);
|
|
switch ((scsirst) & 0x3) {
|
|
case 0:
|
|
printf ("SCSI Controller is running\n");
|
|
break;
|
|
case 1:
|
|
printf ("SCSI Controller is in Power save mode in POS state\n");
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
printf ("SCSI Controller is in Power save mode\n");
|
|
break;
|
|
}
|
|
printf ("SCSI termination is %s\n",
|
|
((scsirst & 0x4) == 0x4) ? "disabled" : "enabled");
|
|
printf ("SCSI Controller is %sreseted\n",
|
|
((scsirst & 0x10) == 0x10) ? "" : "not ");
|
|
printf ("IDE disks are %sreseted\n",
|
|
((scsirst & 0x20) == 0x20) ? "" : "not ");
|
|
printf ("ISA Bus is %sreseted\n",
|
|
((scsirst & 0x40) == 0x40) ? "" : "not ");
|
|
printf ("Super IO is %sreseted\n",
|
|
((scsirst & 0x80) == 0x80) ? "" : "not ");
|
|
}
|
|
|
|
void user_led0 (unsigned char on)
|
|
{
|
|
if (on == TRUE)
|
|
out8 (PLD_LED_USER_REG, (in8 (PLD_LED_USER_REG) | 0x1));
|
|
else
|
|
out8 (PLD_LED_USER_REG, (in8 (PLD_LED_USER_REG) & 0xfe));
|
|
}
|
|
|
|
void user_led1 (unsigned char on)
|
|
{
|
|
if (on == TRUE)
|
|
out8 (PLD_LED_USER_REG, (in8 (PLD_LED_USER_REG) | 0x2));
|
|
else
|
|
out8 (PLD_LED_USER_REG, (in8 (PLD_LED_USER_REG) & 0xfd));
|
|
}
|
|
|
|
void ide_set_reset (int idereset)
|
|
{
|
|
/* if reset = 1 IDE reset will be asserted */
|
|
unsigned char resreg;
|
|
|
|
resreg = in8 (PLD_SCSI_RST_REG);
|
|
if (idereset == 1)
|
|
resreg |= 0x20;
|
|
else {
|
|
udelay(10000);
|
|
resreg &= 0xdf;
|
|
}
|
|
out8 (PLD_SCSI_RST_REG, resreg);
|
|
}
|