powerpc: remove 4xx support

There was for long time no activity in the 4xx area.
We need to go further and convert to Kconfig, but it
turned out, nobody is interested anymore in 4xx,
so remove it.

Signed-off-by: Heiko Schocher <hs@denx.de>
This commit is contained in:
Heiko Schocher
2017-06-27 16:49:14 +02:00
committed by Tom Rini
parent d4db3b86a5
commit 98f705c9ce
471 changed files with 14 additions and 85191 deletions

View File

@ -1,444 +0,0 @@
/*
* arch/powerpc/cpu/ppc4xx/40x_spd_sdram.c
* This SPD SDRAM detection code supports IBM/AMCC PPC44x cpu with a
* SDRAM controller. Those are all current 405 PPC's.
*
* (C) Copyright 2001
* Bill Hunter, Wave 7 Optics, williamhunter@attbi.com
*
* Based on code by:
*
* Kenneth Johansson ,Ericsson AB.
* kenneth.johansson@etx.ericsson.se
*
* hacked up by bill hunter. fixed so we could run before
* serial_init and console_init. previous version avoided this by
* running out of cache memory during serial/console init, then running
* this code later.
*
* (C) Copyright 2002
* Jun Gu, Artesyn Technology, jung@artesyncp.com
* Support for AMCC 440 based on OpenBIOS draminit.c from IBM.
*
* (C) Copyright 2005
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/processor.h>
#include <i2c.h>
#include <asm/ppc4xx.h>
#if defined(CONFIG_SPD_EEPROM) && !defined(CONFIG_440)
/*
* Set default values
*/
#define ONE_BILLION 1000000000
#define SDRAM0_CFG_DCE 0x80000000
#define SDRAM0_CFG_SRE 0x40000000
#define SDRAM0_CFG_PME 0x20000000
#define SDRAM0_CFG_MEMCHK 0x10000000
#define SDRAM0_CFG_REGEN 0x08000000
#define SDRAM0_CFG_ECCDD 0x00400000
#define SDRAM0_CFG_EMDULR 0x00200000
#define SDRAM0_CFG_DRW_SHIFT (31-6)
#define SDRAM0_CFG_BRPF_SHIFT (31-8)
#define SDRAM0_TR_CASL_SHIFT (31-8)
#define SDRAM0_TR_PTA_SHIFT (31-13)
#define SDRAM0_TR_CTP_SHIFT (31-15)
#define SDRAM0_TR_LDF_SHIFT (31-17)
#define SDRAM0_TR_RFTA_SHIFT (31-29)
#define SDRAM0_TR_RCD_SHIFT (31-31)
#define SDRAM0_RTR_SHIFT (31-15)
#define SDRAM0_ECCCFG_SHIFT (31-11)
/* SDRAM0_CFG enable macro */
#define SDRAM0_CFG_BRPF(x) ( ( x & 0x3)<< SDRAM0_CFG_BRPF_SHIFT )
#define SDRAM0_BXCR_SZ_MASK 0x000e0000
#define SDRAM0_BXCR_AM_MASK 0x0000e000
#define SDRAM0_BXCR_SZ_SHIFT (31-14)
#define SDRAM0_BXCR_AM_SHIFT (31-18)
#define SDRAM0_BXCR_SZ(x) ( (( x << SDRAM0_BXCR_SZ_SHIFT) & SDRAM0_BXCR_SZ_MASK) )
#define SDRAM0_BXCR_AM(x) ( (( x << SDRAM0_BXCR_AM_SHIFT) & SDRAM0_BXCR_AM_MASK) )
#ifdef CONFIG_SPDDRAM_SILENT
# define SPD_ERR(x) do { return 0; } while (0)
#else
# define SPD_ERR(x) do { printf(x); return(0); } while (0)
#endif
#define sdram_HZ_to_ns(hertz) (1000000000/(hertz))
/* function prototypes */
int spd_read(uint addr);
/*
* This function is reading data from the DIMM module EEPROM over the SPD bus
* and uses that to program the sdram controller.
*
* This works on boards that has the same schematics that the AMCC walnut has.
*
* Input: null for default I2C spd functions or a pointer to a custom function
* returning spd_data.
*/
long int spd_sdram(int(read_spd)(uint addr))
{
int tmp,row,col;
int total_size,bank_size,bank_code;
int mode;
int bank_cnt;
int sdram0_pmit=0x07c00000;
int sdram0_b0cr;
int sdram0_b1cr = 0;
#ifndef CONFIG_405EP /* not on PPC405EP */
int sdram0_b2cr = 0;
int sdram0_b3cr = 0;
int sdram0_besr0 = -1;
int sdram0_besr1 = -1;
int sdram0_eccesr = -1;
int sdram0_ecccfg;
int ecc_on;
#endif
int sdram0_rtr=0;
int sdram0_tr=0;
int sdram0_cfg=0;
int t_rp;
int t_rcd;
int t_ras;
int t_rc;
int min_cas;
PPC4xx_SYS_INFO sys_info;
unsigned long bus_period_x_10;
/*
* get the board info
*/
get_sys_info(&sys_info);
bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);
if (read_spd == 0){
read_spd=spd_read;
/*
* Make sure I2C controller is initialized
* before continuing.
*/
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
}
/* Make shure we are using SDRAM */
if (read_spd(2) != 0x04) {
SPD_ERR("SDRAM - non SDRAM memory module found\n");
}
/* ------------------------------------------------------------------
* configure memory timing register
*
* data from DIMM:
* 27 IN Row Precharge Time ( t RP)
* 29 MIN RAS to CAS Delay ( t RCD)
* 127 Component and Clock Detail ,clk0-clk3, junction temp, CAS
* -------------------------------------------------------------------*/
/*
* first figure out which cas latency mode to use
* use the min supported mode
*/
tmp = read_spd(127) & 0x6;
if (tmp == 0x02) { /* only cas = 2 supported */
min_cas = 2;
/* t_ck = read_spd(9); */
/* t_ac = read_spd(10); */
} else if (tmp == 0x04) { /* only cas = 3 supported */
min_cas = 3;
/* t_ck = read_spd(9); */
/* t_ac = read_spd(10); */
} else if (tmp == 0x06) { /* 2,3 supported, so use 2 */
min_cas = 2;
/* t_ck = read_spd(23); */
/* t_ac = read_spd(24); */
} else {
SPD_ERR("SDRAM - unsupported CAS latency \n");
}
/* get some timing values, t_rp,t_rcd,t_ras,t_rc
*/
t_rp = read_spd(27);
t_rcd = read_spd(29);
t_ras = read_spd(30);
t_rc = t_ras + t_rp;
/* The following timing calcs subtract 1 before deviding.
* this has effect of using ceiling instead of floor rounding,
* and also subtracting 1 to convert number to reg value
*/
/* set up CASL */
sdram0_tr = (min_cas - 1) << SDRAM0_TR_CASL_SHIFT;
/* set up PTA */
sdram0_tr |= ((((t_rp - 1) * 10)/bus_period_x_10) & 0x3) << SDRAM0_TR_PTA_SHIFT;
/* set up CTP */
tmp = (((t_rc - t_rcd - t_rp -1) * 10) / bus_period_x_10) & 0x3;
if (tmp < 1)
tmp = 1;
sdram0_tr |= tmp << SDRAM0_TR_CTP_SHIFT;
/* set LDF = 2 cycles, reg value = 1 */
sdram0_tr |= 1 << SDRAM0_TR_LDF_SHIFT;
/* set RFTA = t_rfc/bus_period, use t_rfc = t_rc */
tmp = (((t_rc - 1) * 10) / bus_period_x_10) - 3;
if (tmp < 0)
tmp = 0;
if (tmp > 6)
tmp = 6;
sdram0_tr |= tmp << SDRAM0_TR_RFTA_SHIFT;
/* set RCD = t_rcd/bus_period*/
sdram0_tr |= ((((t_rcd - 1) * 10) / bus_period_x_10) &0x3) << SDRAM0_TR_RCD_SHIFT ;
/*------------------------------------------------------------------
* configure RTR register
* -------------------------------------------------------------------*/
row = read_spd(3);
col = read_spd(4);
tmp = read_spd(12) & 0x7f ; /* refresh type less self refresh bit */
switch (tmp) {
case 0x00:
tmp = 15625;
break;
case 0x01:
tmp = 15625 / 4;
break;
case 0x02:
tmp = 15625 / 2;
break;
case 0x03:
tmp = 15625 * 2;
break;
case 0x04:
tmp = 15625 * 4;
break;
case 0x05:
tmp = 15625 * 8;
break;
default:
SPD_ERR("SDRAM - Bad refresh period \n");
}
/* convert from nsec to bus cycles */
tmp = (tmp * 10) / bus_period_x_10;
sdram0_rtr = (tmp & 0x3ff8) << SDRAM0_RTR_SHIFT;
/*------------------------------------------------------------------
* determine the number of banks used
* -------------------------------------------------------------------*/
/* byte 7:6 is module data width */
if (read_spd(7) != 0)
SPD_ERR("SDRAM - unsupported module width\n");
tmp = read_spd(6);
if (tmp < 32)
SPD_ERR("SDRAM - unsupported module width\n");
else if (tmp < 64)
bank_cnt = 1; /* one bank per sdram side */
else if (tmp < 73)
bank_cnt = 2; /* need two banks per side */
else if (tmp < 161)
bank_cnt = 4; /* need four banks per side */
else
SPD_ERR("SDRAM - unsupported module width\n");
/* byte 5 is the module row count (refered to as dimm "sides") */
tmp = read_spd(5);
if (tmp == 1)
;
else if (tmp==2)
bank_cnt *= 2;
else if (tmp==4)
bank_cnt *= 4;
else
bank_cnt = 8; /* 8 is an error code */
if (bank_cnt > 4) /* we only have 4 banks to work with */
SPD_ERR("SDRAM - unsupported module rows for this width\n");
#ifndef CONFIG_405EP /* not on PPC405EP */
/* now check for ECC ability of module. We only support ECC
* on 32 bit wide devices with 8 bit ECC.
*/
if ((read_spd(11)==2) && (read_spd(6)==40) && (read_spd(14)==8)) {
sdram0_ecccfg = 0xf << SDRAM0_ECCCFG_SHIFT;
ecc_on = 1;
} else {
sdram0_ecccfg = 0;
ecc_on = 0;
}
#endif
/*------------------------------------------------------------------
* calculate total size
* -------------------------------------------------------------------*/
/* calculate total size and do sanity check */
tmp = read_spd(31);
total_size = 1 << 22; /* total_size = 4MB */
/* now multiply 4M by the smallest device row density */
/* note that we don't support asymetric rows */
while (((tmp & 0x0001) == 0) && (tmp != 0)) {
total_size = total_size << 1;
tmp = tmp >> 1;
}
total_size *= read_spd(5); /* mult by module rows (dimm sides) */
/*------------------------------------------------------------------
* map rows * cols * banks to a mode
* -------------------------------------------------------------------*/
switch (row) {
case 11:
switch (col) {
case 8:
mode=4; /* mode 5 */
break;
case 9:
case 10:
mode=0; /* mode 1 */
break;
default:
SPD_ERR("SDRAM - unsupported mode\n");
}
break;
case 12:
switch (col) {
case 8:
mode=3; /* mode 4 */
break;
case 9:
case 10:
mode=1; /* mode 2 */
break;
default:
SPD_ERR("SDRAM - unsupported mode\n");
}
break;
case 13:
switch (col) {
case 8:
mode=5; /* mode 6 */
break;
case 9:
case 10:
if (read_spd(17) == 2)
mode = 6; /* mode 7 */
else
mode = 2; /* mode 3 */
break;
case 11:
mode = 2; /* mode 3 */
break;
default:
SPD_ERR("SDRAM - unsupported mode\n");
}
break;
default:
SPD_ERR("SDRAM - unsupported mode\n");
}
/*------------------------------------------------------------------
* using the calculated values, compute the bank
* config register values.
* -------------------------------------------------------------------*/
/* compute the size of each bank */
bank_size = total_size / bank_cnt;
/* convert bank size to bank size code for ppc4xx
by takeing log2(bank_size) - 22 */
tmp = bank_size; /* start with tmp = bank_size */
bank_code = 0; /* and bank_code = 0 */
while (tmp > 1) { /* this takes log2 of tmp */
bank_code++; /* and stores result in bank_code */
tmp = tmp >> 1;
} /* bank_code is now log2(bank_size) */
bank_code -= 22; /* subtract 22 to get the code */
tmp = SDRAM0_BXCR_SZ(bank_code) | SDRAM0_BXCR_AM(mode) | 1;
sdram0_b0cr = (bank_size * 0) | tmp;
#ifndef CONFIG_405EP /* not on PPC405EP */
if (bank_cnt > 1)
sdram0_b2cr = (bank_size * 1) | tmp;
if (bank_cnt > 2)
sdram0_b1cr = (bank_size * 2) | tmp;
if (bank_cnt > 3)
sdram0_b3cr = (bank_size * 3) | tmp;
#else
/* PPC405EP chip only supports two SDRAM banks */
if (bank_cnt > 1)
sdram0_b1cr = (bank_size * 1) | tmp;
if (bank_cnt > 2)
total_size = 2 * bank_size;
#endif
/*
* enable sdram controller DCE=1
* enable burst read prefetch to 32 bytes BRPF=2
* leave other functions off
*/
/*------------------------------------------------------------------
* now that we've done our calculations, we are ready to
* program all the registers.
* -------------------------------------------------------------------*/
/* disable memcontroller so updates work */
mtsdram(SDRAM0_CFG, 0);
#ifndef CONFIG_405EP /* not on PPC405EP */
mtsdram(SDRAM0_BESR0, sdram0_besr0);
mtsdram(SDRAM0_BESR1, sdram0_besr1);
mtsdram(SDRAM0_ECCCFG, sdram0_ecccfg);
mtsdram(SDRAM0_ECCESR, sdram0_eccesr);
#endif
mtsdram(SDRAM0_RTR, sdram0_rtr);
mtsdram(SDRAM0_PMIT, sdram0_pmit);
mtsdram(SDRAM0_B0CR, sdram0_b0cr);
mtsdram(SDRAM0_B1CR, sdram0_b1cr);
#ifndef CONFIG_405EP /* not on PPC405EP */
mtsdram(SDRAM0_B2CR, sdram0_b2cr);
mtsdram(SDRAM0_B3CR, sdram0_b3cr);
#endif
mtsdram(SDRAM0_TR, sdram0_tr);
/* SDRAM have a power on delay, 500 micro should do */
udelay(500);
sdram0_cfg = SDRAM0_CFG_DCE | SDRAM0_CFG_BRPF(1) | SDRAM0_CFG_ECCDD | SDRAM0_CFG_EMDULR;
#ifndef CONFIG_405EP /* not on PPC405EP */
if (ecc_on)
sdram0_cfg |= SDRAM0_CFG_MEMCHK;
#endif
mtsdram(SDRAM0_CFG, sdram0_cfg);
return (total_size);
}
int spd_read(uint addr)
{
uchar data[2];
if (i2c_read(SPD_EEPROM_ADDRESS, addr, 1, data, 1) == 0)
return (int)data[0];
else
return 0;
}
#endif /* CONFIG_SPD_EEPROM */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,863 +0,0 @@
/*
* SPDX-License-Identifier: GPL-2.0 IBM-pibs
*
* File Name: 405gp_pci.c
*
* Function: Initialization code for the 405GP PCI Configuration regs.
*
* Author: Mark Game
*
* Change Activity-
*
* Date Description of Change BY
* --------- --------------------- ---
* 09-Sep-98 Created MCG
* 02-Nov-98 Removed External arbiter selected message JWB
* 27-Nov-98 Zero out PTMBAR2 and disable in PTM2MS JWB
* 04-Jan-99 Zero out other unused PMM and PTM regs. Change bus scan MCG
* from (0 to n) to (1 to n).
* 17-May-99 Port to Walnut JWB
* 17-Jun-99 Updated for VGA support JWB
* 21-Jun-99 Updated to allow SRAM region to be a target from PCI bus JWB
* 19-Jul-99 Updated for 405GP pass 1 errata #26 (Low PCI subsequent MCG
* target latency timer values are not supported).
* Should be fixed in pass 2.
* 09-Sep-99 Removed use of PTM2 since the SRAM region no longer needs JWB
* to be a PCI target. Zero out PTMBAR2 and disable in PTM2MS.
* 10-Dec-99 Updated PCI_Write_CFG_Reg for pass2 errata #6 JWB
* 11-Jan-00 Ensure PMMxMAs disabled before setting PMMxLAs. This is not
* really required after a reset since PMMxMAs are already
* disabled but is a good practice nonetheless. JWB
* 12-Jun-01 stefan.roese@esd-electronics.com
* - PCI host/adapter handling reworked
* 09-Jul-01 stefan.roese@esd-electronics.com
* - PCI host now configures from device 0 (not 1) to max_dev,
* (host configures itself)
* - On CPCI-405 pci base address and size is generated from
* SDRAM and FLASH size (CFG regs not used anymore)
* - Some minor changes for CPCI-405-A (adapter version)
* 14-Sep-01 stefan.roese@esd-electronics.com
* - CONFIG_PCI_SCAN_SHOW added to print pci devices upon startup
* 28-Sep-01 stefan.roese@esd-electronics.com
* - Changed pci master configuration for linux compatibility
* (no need for bios_fixup() anymore)
* 26-Feb-02 stefan.roese@esd-electronics.com
* - Bug fixed in pci configuration (Andrew May)
* - Removed pci class code init for CPCI405 board
* 15-May-02 stefan.roese@esd-electronics.com
* - New vga device handling
* 29-May-02 stefan.roese@esd-electronics.com
* - PCI class code init added (if defined)
*----------------------------------------------------------------------------*/
#include <common.h>
#include <command.h>
#include <asm/4xx_pci.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <pci.h>
#include <asm/ppc4xx.h>
#ifdef CONFIG_PCI
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
/*#define DEBUG*/
/*
* Board-specific pci initialization
* Platform code can reimplement pci_pre_init() if needed
*/
int __pci_pre_init(struct pci_controller *hose)
{
#if defined(CONFIG_405EP)
/*
* Enable the internal PCI arbiter by default.
*
* On 405EP CPUs the internal arbiter can be controlled
* by the I2C strapping EEPROM. If you want to do so
* or if you want to disable the arbiter pci_pre_init()
* must be reimplemented without enabling the arbiter.
* The arbiter is enabled in this place because of
* compatibility reasons.
*/
mtdcr(CPC0_PCI, mfdcr(CPC0_PCI) | CPC0_PCI_ARBIT_EN);
#endif /* CONFIG_405EP */
return 1;
}
int pci_pre_init(struct pci_controller *hose)
__attribute__((weak, alias("__pci_pre_init")));
int __is_pci_host(struct pci_controller *hose)
{
#if defined(CONFIG_405GP)
if (mfdcr(CPC0_PSR) & PSR_PCI_ARBIT_EN)
return 1;
#elif defined (CONFIG_405EP)
if (mfdcr(CPC0_PCI) & CPC0_PCI_ARBIT_EN)
return 1;
#endif
return 0;
}
int is_pci_host(struct pci_controller *hose) __attribute__((weak, alias("__is_pci_host")));
/*-----------------------------------------------------------------------------+
* pci_init. Initializes the 405GP PCI Configuration regs.
*-----------------------------------------------------------------------------*/
void pci_405gp_init(struct pci_controller *hose)
{
int i, reg_num = 0;
bd_t *bd = gd->bd;
unsigned short temp_short;
unsigned long ptmpcila[2] = {CONFIG_SYS_PCI_PTM1PCI, CONFIG_SYS_PCI_PTM2PCI};
#if defined(CONFIG_PCI_4xx_PTM_OVERWRITE)
char *ptmla_str, *ptmms_str;
#endif
unsigned long ptmla[2] = {CONFIG_SYS_PCI_PTM1LA, CONFIG_SYS_PCI_PTM2LA};
unsigned long ptmms[2] = {CONFIG_SYS_PCI_PTM1MS, CONFIG_SYS_PCI_PTM2MS};
#if defined(CONFIG_PIP405) || defined(CONFIG_TARGET_MIP405) \
|| defined(CONFIG_TARGET_MIP405T)
unsigned long pmmla[3] = {0x80000000, 0xA0000000, 0};
unsigned long pmmma[3] = {0xE0000001, 0xE0000001, 0};
unsigned long pmmpcila[3] = {0x80000000, 0x00000000, 0};
unsigned long pmmpciha[3] = {0x00000000, 0x00000000, 0};
#else
unsigned long pmmla[3] = {0x80000000, 0,0};
unsigned long pmmma[3] = {0xC0000001, 0,0};
unsigned long pmmpcila[3] = {0x80000000, 0,0};
unsigned long pmmpciha[3] = {0x00000000, 0,0};
#endif
#ifdef CONFIG_PCI_PNP
#if (CONFIG_PCI_HOST == PCI_HOST_AUTO)
char *s;
#endif
#endif
#if defined(CONFIG_PCI_4xx_PTM_OVERWRITE)
ptmla_str = getenv("ptm1la");
ptmms_str = getenv("ptm1ms");
if(NULL != ptmla_str && NULL != ptmms_str ) {
ptmla[0] = simple_strtoul (ptmla_str, NULL, 16);
ptmms[0] = simple_strtoul (ptmms_str, NULL, 16);
}
ptmla_str = getenv("ptm2la");
ptmms_str = getenv("ptm2ms");
if(NULL != ptmla_str && NULL != ptmms_str ) {
ptmla[1] = simple_strtoul (ptmla_str, NULL, 16);
ptmms[1] = simple_strtoul (ptmms_str, NULL, 16);
}
#endif
/*
* Register the hose
*/
hose->first_busno = 0;
hose->last_busno = 0xff;
/* ISA/PCI I/O space */
pci_set_region(hose->regions + reg_num++,
MIN_PCI_PCI_IOADDR,
MIN_PLB_PCI_IOADDR,
0x10000,
PCI_REGION_IO);
/* PCI I/O space */
pci_set_region(hose->regions + reg_num++,
0x00800000,
0xe8800000,
0x03800000,
PCI_REGION_IO);
reg_num = 2;
/* Memory spaces */
for (i=0; i<2; i++)
if (ptmms[i] & 1)
{
if (!i) hose->pci_fb = hose->regions + reg_num;
pci_set_region(hose->regions + reg_num++,
ptmpcila[i], ptmla[i],
~(ptmms[i] & 0xfffff000) + 1,
PCI_REGION_MEM |
PCI_REGION_SYS_MEMORY);
}
/* PCI memory spaces */
for (i=0; i<3; i++)
if (pmmma[i] & 1)
{
pci_set_region(hose->regions + reg_num++,
pmmpcila[i], pmmla[i],
~(pmmma[i] & 0xfffff000) + 1,
PCI_REGION_MEM);
}
hose->region_count = reg_num;
pci_setup_indirect(hose,
PCICFGADR,
PCICFGDATA);
if (hose->pci_fb)
pciauto_region_init(hose->pci_fb);
/* Let board change/modify hose & do initial checks */
if (pci_pre_init(hose) == 0) {
printf("PCI: Board-specific initialization failed.\n");
printf("PCI: Configuration aborted.\n");
return;
}
pci_register_hose(hose);
/*--------------------------------------------------------------------------+
* 405GP PCI Master configuration.
* Map one 512 MB range of PLB/processor addresses to PCI memory space.
* PLB address 0x80000000-0xBFFFFFFF ==> PCI address 0x80000000-0xBFFFFFFF
* Use byte reversed out routines to handle endianess.
*--------------------------------------------------------------------------*/
out32r(PMM0MA, (pmmma[0]&~0x1)); /* disable, configure PMMxLA, PMMxPCILA first */
out32r(PMM0LA, pmmla[0]);
out32r(PMM0PCILA, pmmpcila[0]);
out32r(PMM0PCIHA, pmmpciha[0]);
out32r(PMM0MA, pmmma[0]);
/*--------------------------------------------------------------------------+
* PMM1 is not used. Initialize them to zero.
*--------------------------------------------------------------------------*/
out32r(PMM1MA, (pmmma[1]&~0x1));
out32r(PMM1LA, pmmla[1]);
out32r(PMM1PCILA, pmmpcila[1]);
out32r(PMM1PCIHA, pmmpciha[1]);
out32r(PMM1MA, pmmma[1]);
/*--------------------------------------------------------------------------+
* PMM2 is not used. Initialize them to zero.
*--------------------------------------------------------------------------*/
out32r(PMM2MA, (pmmma[2]&~0x1));
out32r(PMM2LA, pmmla[2]);
out32r(PMM2PCILA, pmmpcila[2]);
out32r(PMM2PCIHA, pmmpciha[2]);
out32r(PMM2MA, pmmma[2]);
/*--------------------------------------------------------------------------+
* 405GP PCI Target configuration. (PTM1)
* Note: PTM1MS is hardwire enabled but we set the enable bit anyway.
*--------------------------------------------------------------------------*/
out32r(PTM1LA, ptmla[0]); /* insert address */
out32r(PTM1MS, ptmms[0]); /* insert size, enable bit is 1 */
pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1, ptmpcila[0]);
/*--------------------------------------------------------------------------+
* 405GP PCI Target configuration. (PTM2)
*--------------------------------------------------------------------------*/
out32r(PTM2LA, ptmla[1]); /* insert address */
pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, ptmpcila[1]);
if (ptmms[1] == 0)
{
out32r(PTM2MS, 0x00000001); /* set enable bit */
pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, 0x00000000);
out32r(PTM2MS, 0x00000000); /* disable */
}
else
{
out32r(PTM2MS, ptmms[1]); /* insert size, enable bit is 1 */
}
/*
* Insert Subsystem Vendor and Device ID
*/
pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_VENDOR_ID, CONFIG_SYS_PCI_SUBSYS_VENDORID);
#ifdef CONFIG_CPCI405
if (is_pci_host(hose))
pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_DEVICEID);
else
pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_DEVICEID2);
#else
pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_DEVICEID);
#endif
/*
* Insert Class-code
*/
#ifdef CONFIG_SYS_PCI_CLASSCODE
pci_write_config_word(PCIDEVID_405GP, PCI_CLASS_SUB_CODE, CONFIG_SYS_PCI_CLASSCODE);
#endif /* CONFIG_SYS_PCI_CLASSCODE */
/*--------------------------------------------------------------------------+
* If PCI speed = 66MHz, set 66MHz capable bit.
*--------------------------------------------------------------------------*/
if (bd->bi_pci_busfreq >= 66000000) {
pci_read_config_word(PCIDEVID_405GP, PCI_STATUS, &temp_short);
pci_write_config_word(PCIDEVID_405GP,PCI_STATUS,(temp_short|PCI_STATUS_66MHZ));
}
#if (CONFIG_PCI_HOST != PCI_HOST_ADAPTER)
#if (CONFIG_PCI_HOST == PCI_HOST_AUTO)
if (is_pci_host(hose) ||
(((s = getenv("pciscan")) != NULL) && (strcmp(s, "yes") == 0)))
#endif
{
/*--------------------------------------------------------------------------+
* Write the 405GP PCI Configuration regs.
* Enable 405GP to be a master on the PCI bus (PMM).
* Enable 405GP to act as a PCI memory target (PTM).
*--------------------------------------------------------------------------*/
pci_read_config_word(PCIDEVID_405GP, PCI_COMMAND, &temp_short);
pci_write_config_word(PCIDEVID_405GP, PCI_COMMAND, temp_short |
PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
}
#endif
#if defined(CONFIG_405EP)
/*
* on ppc405ep vendor/device id is not set
* The user manual says 0x1014 (IBM) / 0x0156 (405GP!)
* are the correct values.
*/
pci_write_config_word(PCIDEVID_405GP, PCI_VENDOR_ID, PCI_VENDOR_ID_IBM);
pci_write_config_word(PCIDEVID_405GP,
PCI_DEVICE_ID, PCI_DEVICE_ID_IBM_405GP);
#endif
/*
* Set HCE bit (Host Configuration Enabled)
*/
pci_read_config_word(PCIDEVID_405GP, PCIBRDGOPT2, &temp_short);
pci_write_config_word(PCIDEVID_405GP, PCIBRDGOPT2, (temp_short | 0x0001));
#ifdef CONFIG_PCI_PNP
/*--------------------------------------------------------------------------+
* Scan the PCI bus and configure devices found.
*--------------------------------------------------------------------------*/
#if (CONFIG_PCI_HOST == PCI_HOST_AUTO)
if (is_pci_host(hose) ||
(((s = getenv("pciscan")) != NULL) && (strcmp(s, "yes") == 0)))
#endif
{
#ifdef CONFIG_PCI_SCAN_SHOW
printf("PCI: Bus Dev VenId DevId Class Int\n");
#endif
hose->last_busno = pci_hose_scan(hose);
}
#endif /* CONFIG_PCI_PNP */
}
/*
* drivers/pci/pci.c skips every host bridge but the 405GP since it could
* be set as an Adapter.
*
* I (Andrew May) don't know what we should do here, but I don't want
* the auto setup of a PCI device disabling what is done pci_405gp_init
* as has happened before.
*/
void pci_405gp_setup_bridge(struct pci_controller *hose, pci_dev_t dev,
struct pci_config_table *entry)
{
#ifdef DEBUG
printf("405gp_setup_bridge\n");
#endif
}
/*
*
*/
void pci_405gp_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
{
unsigned char int_line = 0xff;
/*
* Write pci interrupt line register (cpci405 specific)
*/
switch (PCI_DEV(dev) & 0x03)
{
case 0:
int_line = 27 + 2;
break;
case 1:
int_line = 27 + 3;
break;
case 2:
int_line = 27 + 0;
break;
case 3:
int_line = 27 + 1;
break;
}
pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line);
}
void pci_405gp_setup_vga(struct pci_controller *hose, pci_dev_t dev,
struct pci_config_table *entry)
{
unsigned int cmdstat = 0;
pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
/* always enable io space on vga boards */
pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat);
cmdstat |= PCI_COMMAND_IO;
pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat);
}
#if !(defined(CONFIG_PIP405) || defined(CONFIG_TARGET_MIP405) \
|| defined(CONFIG_TARGET_MIP405T))
/*
*As is these functs get called out of flash Not a horrible
*thing, but something to keep in mind. (no statics?)
*/
static struct pci_config_table pci_405gp_config_table[] = {
/*if VendID is 0 it terminates the table search (ie Walnut)*/
#ifdef CONFIG_SYS_PCI_SUBSYS_VENDORID
{CONFIG_SYS_PCI_SUBSYS_VENDORID, PCI_ANY_ID, PCI_CLASS_BRIDGE_HOST,
PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, pci_405gp_setup_bridge},
#endif
{PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA,
PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, pci_405gp_setup_vga},
{PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NOT_DEFINED_VGA,
PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, pci_405gp_setup_vga},
{ }
};
static struct pci_controller hose = {
fixup_irq: pci_405gp_fixup_irq,
config_table: pci_405gp_config_table,
};
void pci_init_board(void)
{
/*we want the ptrs to RAM not flash (ie don't use init list)*/
hose.fixup_irq = pci_405gp_fixup_irq;
hose.config_table = pci_405gp_config_table;
pci_405gp_init(&hose);
}
#endif
#endif /* CONFIG_405GP */
/*-----------------------------------------------------------------------------+
* CONFIG_440
*-----------------------------------------------------------------------------*/
#if defined(CONFIG_440)
#if defined(CONFIG_SYS_PCI_MASTER_INIT) || defined(CONFIG_SYS_PCI_TARGET_INIT)
static struct pci_controller ppc440_hose = {0};
#endif
/*
* This routine is called to determine if a pci scan should be
* performed. With various hardware environments (especially cPCI and
* PPMC) it's insufficient to depend on the state of the arbiter enable
* bit in the strap register, or generic host/adapter assumptions.
*
* Rather than hard-code a bad assumption in the general 440 code, the
* 440 pci code requires the board to decide at runtime.
*
* Return 0 for adapter mode, non-zero for host (monarch) mode.
*
* Weak default implementation: "Normal" boards implement the PCI
* host functionality. This can be overridden for PCI adapter boards.
*/
int __is_pci_host(struct pci_controller *hose)
{
return 1;
}
int is_pci_host(struct pci_controller *hose)
__attribute__((weak, alias("__is_pci_host")));
#if defined(CONFIG_440EP) || defined(CONFIG_440EPX) || \
defined(CONFIG_440GR) || defined(CONFIG_440GRX)
#if defined(CONFIG_SYS_PCI_TARGET_INIT)
/*
* pci_target_init
*
* The bootstrap configuration provides default settings for the pci
* inbound map (PIM). But the bootstrap config choices are limited and
* may not be sufficient for a given board.
*/
void __pci_target_init(struct pci_controller *hose)
{
/*
* Set up Direct MMIO registers
*/
/*
* PowerPC440 EP PCI Master configuration.
* Map one 1Gig range of PLB/processor addresses to PCI memory space.
* PLB address 0xA0000000-0xDFFFFFFF ==> PCI address 0xA0000000-0xDFFFFFFF
* Use byte reversed out routines to handle endianess.
* Make this region non-prefetchable.
*/
/* PMM0 Mask/Attribute - disabled b4 setting */
out_le32((void *)PCIL0_PMM0MA, 0x00000000);
/* PMM0 Local Address */
out_le32((void *)PCIL0_PMM0LA, CONFIG_SYS_PCI_MEMBASE);
/* PMM0 PCI Low Address */
out_le32((void *)PCIL0_PMM0PCILA, CONFIG_SYS_PCI_MEMBASE);
/* PMM0 PCI High Address */
out_le32((void *)PCIL0_PMM0PCIHA, 0x00000000);
/* 512M + No prefetching, and enable region */
out_le32((void *)PCIL0_PMM0MA, 0xE0000001);
/* PMM1 Mask/Attribute - disabled b4 setting */
out_le32((void *)PCIL0_PMM1MA, 0x00000000);
/* PMM1 Local Address */
out_le32((void *)PCIL0_PMM1LA, CONFIG_SYS_PCI_MEMBASE2);
/* PMM1 PCI Low Address */
out_le32((void *)PCIL0_PMM1PCILA, CONFIG_SYS_PCI_MEMBASE2);
/* PMM1 PCI High Address */
out_le32((void *)PCIL0_PMM1PCIHA, 0x00000000);
/* 512M + No prefetching, and enable region */
out_le32((void *)PCIL0_PMM1MA, 0xE0000001);
out_le32((void *)PCIL0_PTM1MS, 0x00000001); /* Memory Size/Attribute */
out_le32((void *)PCIL0_PTM1LA, 0); /* Local Addr. Reg */
out_le32((void *)PCIL0_PTM2MS, 0); /* Memory Size/Attribute */
out_le32((void *)PCIL0_PTM2LA, 0); /* Local Addr. Reg */
/*
* Set up Configuration registers
*/
/* Program the board's subsystem id/vendor id */
pci_write_config_word(0, PCI_SUBSYSTEM_VENDOR_ID,
CONFIG_SYS_PCI_SUBSYS_VENDORID);
pci_write_config_word(0, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_ID);
/* Configure command register as bus master */
pci_write_config_word(0, PCI_COMMAND, PCI_COMMAND_MASTER);
/* 240nS PCI clock */
pci_write_config_word(0, PCI_LATENCY_TIMER, 1);
/* No error reporting */
pci_write_config_word(0, PCI_ERREN, 0);
pci_write_config_dword(0, PCI_BRDGOPT2, 0x00000101);
}
#endif /* CONFIG_SYS_PCI_TARGET_INIT */
/*
* pci_pre_init
*
* This routine is called just prior to registering the hose and gives
* the board the opportunity to check things. Returning a value of zero
* indicates that things are bad & PCI initialization should be aborted.
*
* Different boards may wish to customize the pci controller structure
* (add regions, override default access routines, etc) or perform
* certain pre-initialization actions.
*
*/
int __pci_pre_init(struct pci_controller *hose)
{
u32 reg;
/*
* Set priority for all PLB3 devices to 0.
* Set PLB3 arbiter to fair mode.
*/
mfsdr(SDR0_AMP1, reg);
mtsdr(SDR0_AMP1, (reg & 0x000000FF) | 0x0000FF00);
reg = mfdcr(PLB3A0_ACR);
mtdcr(PLB3A0_ACR, reg | 0x80000000);
/*
* Set priority for all PLB4 devices to 0.
*/
mfsdr(SDR0_AMP0, reg);
mtsdr(SDR0_AMP0, (reg & 0x000000FF) | 0x0000FF00);
reg = mfdcr(PLB4A0_ACR) | 0xa0000000;
mtdcr(PLB4A0_ACR, reg);
/*
* Set Nebula PLB4 arbiter to fair mode.
*/
/* Segment0 */
reg = (mfdcr(PLB4A0_ACR) & ~PLB4Ax_ACR_PPM_MASK) | PLB4Ax_ACR_PPM_FAIR;
reg = (reg & ~PLB4Ax_ACR_HBU_MASK) | PLB4Ax_ACR_HBU_ENABLED;
reg = (reg & ~PLB4Ax_ACR_RDP_MASK) | PLB4Ax_ACR_RDP_4DEEP;
reg = (reg & ~PLB4Ax_ACR_WRP_MASK) | PLB4Ax_ACR_WRP_2DEEP;
mtdcr(PLB4A0_ACR, reg);
/* Segment1 */
reg = (mfdcr(PLB4A1_ACR) & ~PLB4Ax_ACR_PPM_MASK) | PLB4Ax_ACR_PPM_FAIR;
reg = (reg & ~PLB4Ax_ACR_HBU_MASK) | PLB4Ax_ACR_HBU_ENABLED;
reg = (reg & ~PLB4Ax_ACR_RDP_MASK) | PLB4Ax_ACR_RDP_4DEEP;
reg = (reg & ~PLB4Ax_ACR_WRP_MASK) | PLB4Ax_ACR_WRP_2DEEP;
mtdcr(PLB4A1_ACR, reg);
#if defined(CONFIG_SYS_PCI_BOARD_FIXUP_IRQ)
hose->fixup_irq = board_pci_fixup_irq;
#endif
return 1;
}
#else /* defined(CONFIG_440EP) ... */
#if defined(CONFIG_SYS_PCI_TARGET_INIT)
void __pci_target_init(struct pci_controller * hose)
{
/*
* Disable everything
*/
out_le32((void *)PCIL0_PIM0SA, 0); /* disable */
out_le32((void *)PCIL0_PIM1SA, 0); /* disable */
out_le32((void *)PCIL0_PIM2SA, 0); /* disable */
out_le32((void *)PCIL0_EROMBA, 0); /* disable expansion rom */
/*
* Map all of SDRAM to PCI address 0x0000_0000. Note that the 440
* strapping options do not support sizes such as 128/256 MB.
*/
out_le32((void *)PCIL0_PIM0LAL, CONFIG_SYS_SDRAM_BASE);
out_le32((void *)PCIL0_PIM0LAH, 0);
out_le32((void *)PCIL0_PIM0SA, ~(gd->ram_size - 1) | 1);
out_le32((void *)PCIL0_BAR0, 0);
/*
* Program the board's subsystem id/vendor id
*/
out_le16((void *)PCIL0_SBSYSVID, CONFIG_SYS_PCI_SUBSYS_VENDORID);
out_le16((void *)PCIL0_SBSYSID, CONFIG_SYS_PCI_SUBSYS_DEVICEID);
out_le16((void *)PCIL0_CMD, in_le16((void *)PCIL0_CMD) |
PCI_COMMAND_MEMORY);
}
#endif /* CONFIG_SYS_PCI_TARGET_INIT */
int __pci_pre_init(struct pci_controller *hose)
{
/*
* This board is always configured as the host & requires the
* PCI arbiter to be enabled.
*/
if (!pci_arbiter_enabled()) {
printf("PCI: PCI Arbiter disabled!\n");
return 0;
}
return 1;
}
#endif /* defined(CONFIG_440EP) ... */
#if defined(CONFIG_SYS_PCI_TARGET_INIT)
void pci_target_init(struct pci_controller * hose)
__attribute__((weak, alias("__pci_target_init")));
#endif /* CONFIG_SYS_PCI_TARGET_INIT */
int pci_pre_init(struct pci_controller *hose)
__attribute__((weak, alias("__pci_pre_init")));
#if defined(CONFIG_SYS_PCI_MASTER_INIT)
void __pci_master_init(struct pci_controller *hose)
{
u16 reg;
/*
* Write the PowerPC440 EP PCI Configuration regs.
* Enable PowerPC440 EP to be a master on the PCI bus (PMM).
* Enable PowerPC440 EP to act as a PCI memory target (PTM).
*/
pci_read_config_word(0, PCI_COMMAND, &reg);
pci_write_config_word(0, PCI_COMMAND, reg |
PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
}
void pci_master_init(struct pci_controller *hose)
__attribute__((weak, alias("__pci_master_init")));
#endif /* CONFIG_SYS_PCI_MASTER_INIT */
#if defined(CONFIG_SYS_PCI_MASTER_INIT) || defined(CONFIG_SYS_PCI_TARGET_INIT)
static int pci_440_init (struct pci_controller *hose)
{
int reg_num = 0;
#ifndef CONFIG_DISABLE_PISE_TEST
/*--------------------------------------------------------------------------+
* The PCI initialization sequence enable bit must be set ... if not abort
* pci setup since updating the bit requires chip reset.
*--------------------------------------------------------------------------*/
#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
unsigned long strap;
mfsdr(SDR0_SDSTP1,strap);
if ((strap & SDR0_SDSTP1_PISE_MASK) == 0) {
printf("PCI: SDR0_STRP1[PISE] not set.\n");
printf("PCI: Configuration aborted.\n");
return -1;
}
#elif defined(CONFIG_440GP)
unsigned long strap;
strap = mfdcr(CPC0_STRP1);
if ((strap & CPC0_STRP1_PISE_MASK) == 0) {
printf("PCI: CPC0_STRP1[PISE] not set.\n");
printf("PCI: Configuration aborted.\n");
return -1;
}
#endif
#endif /* CONFIG_DISABLE_PISE_TEST */
/*--------------------------------------------------------------------------+
* PCI controller init
*--------------------------------------------------------------------------*/
hose->first_busno = 0;
hose->last_busno = 0;
/* PCI I/O space */
pci_set_region(hose->regions + reg_num++,
0x00000000,
PCIL0_IOBASE,
0x10000,
PCI_REGION_IO);
/* PCI memory space */
pci_set_region(hose->regions + reg_num++,
CONFIG_SYS_PCI_TARGBASE,
CONFIG_SYS_PCI_MEMBASE,
#ifdef CONFIG_SYS_PCI_MEMSIZE
CONFIG_SYS_PCI_MEMSIZE,
#else
0x10000000,
#endif
PCI_REGION_MEM );
#if defined(CONFIG_PCI_SYS_MEM_BUS) && defined(CONFIG_PCI_SYS_MEM_PHYS) && \
defined(CONFIG_PCI_SYS_MEM_SIZE)
/* System memory space */
pci_set_region(hose->regions + reg_num++,
CONFIG_PCI_SYS_MEM_BUS,
CONFIG_PCI_SYS_MEM_PHYS,
CONFIG_PCI_SYS_MEM_SIZE,
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY );
#endif
hose->region_count = reg_num;
pci_setup_indirect(hose, PCIL0_CFGADR, PCIL0_CFGDATA);
/* Let board change/modify hose & do initial checks */
if (pci_pre_init(hose) == 0) {
printf("PCI: Board-specific initialization failed.\n");
printf("PCI: Configuration aborted.\n");
return -1;
}
pci_register_hose( hose );
/*--------------------------------------------------------------------------+
* PCI target init
*--------------------------------------------------------------------------*/
#if defined(CONFIG_SYS_PCI_TARGET_INIT)
pci_target_init(hose); /* Let board setup pci target */
#else
out16r( PCIL0_SBSYSVID, CONFIG_SYS_PCI_SUBSYS_VENDORID );
out16r( PCIL0_SBSYSID, CONFIG_SYS_PCI_SUBSYS_ID );
out16r( PCIL0_CLS, 0x00060000 ); /* Bridge, host bridge */
#endif
#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
out32r( PCIL0_BRDGOPT1, 0x04000060 ); /* PLB Rq pri highest */
out32r( PCIL0_BRDGOPT2, in32(PCIL0_BRDGOPT2) | 0x83 ); /* Enable host config, clear Timeout, ensure int src1 */
#elif defined(PCIL0_BRDGOPT1)
out32r( PCIL0_BRDGOPT1, 0x10000060 ); /* PLB Rq pri highest */
out32r( PCIL0_BRDGOPT2, in32(PCIL0_BRDGOPT2) | 1 ); /* Enable host config */
#endif
/*--------------------------------------------------------------------------+
* PCI master init: default is one 256MB region for PCI memory:
* 0x3_00000000 - 0x3_0FFFFFFF ==> CONFIG_SYS_PCI_MEMBASE
*--------------------------------------------------------------------------*/
#if defined(CONFIG_SYS_PCI_MASTER_INIT)
pci_master_init(hose); /* Let board setup pci master */
#else
out32r( PCIL0_POM0SA, 0 ); /* disable */
out32r( PCIL0_POM1SA, 0 ); /* disable */
out32r( PCIL0_POM2SA, 0 ); /* disable */
#if defined(CONFIG_440SPE)
out32r( PCIL0_POM0LAL, 0x10000000 );
out32r( PCIL0_POM0LAH, 0x0000000c );
#elif defined(CONFIG_460EX) || defined(CONFIG_460GT)
out32r( PCIL0_POM0LAL, 0x20000000 );
out32r( PCIL0_POM0LAH, 0x0000000c );
#else
out32r( PCIL0_POM0LAL, 0x00000000 );
out32r( PCIL0_POM0LAH, 0x00000003 );
#endif
out32r( PCIL0_POM0PCIAL, CONFIG_SYS_PCI_MEMBASE );
out32r( PCIL0_POM0PCIAH, 0x00000000 );
out32r( PCIL0_POM0SA, 0xf0000001 ); /* 256MB, enabled */
out32r( PCIL0_STS, in32r( PCIL0_STS ) & ~0x0000fff8 );
#endif
/*--------------------------------------------------------------------------+
* PCI host configuration -- we don't make any assumptions here ... the
* _board_must_indicate_ what to do -- there's just too many runtime
* scenarios in environments like cPCI, PPMC, etc. to make a determination
* based on hard-coded values or state of arbiter enable.
*--------------------------------------------------------------------------*/
if (is_pci_host(hose)) {
#ifdef CONFIG_PCI_SCAN_SHOW
printf("PCI: Bus Dev VenId DevId Class Int\n");
#endif
#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) && \
!defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
out16r( PCIL0_CMD, in16r( PCIL0_CMD ) | PCI_COMMAND_MASTER);
#endif
hose->last_busno = pci_hose_scan(hose);
}
return hose->last_busno;
}
#endif
void pci_init_board(void)
{
int busno = 0;
/*
* Only init PCI when either master or target functionality
* is selected.
*/
#if defined(CONFIG_SYS_PCI_MASTER_INIT) || defined(CONFIG_SYS_PCI_TARGET_INIT)
busno = pci_440_init(&ppc440_hose);
if (busno < 0)
return;
#endif
#if (defined(CONFIG_440SPE) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)) && \
!defined(CONFIG_PCI_DISABLE_PCIE)
pcie_setup_hoses(busno + 1);
#endif
}
#endif /* CONFIG_440 */
#if defined(CONFIG_405EX)
void pci_init_board(void)
{
#ifdef CONFIG_PCI_SCAN_SHOW
printf("PCI: Bus Dev VenId DevId Class Int\n");
#endif
pcie_setup_hoses(0);
}
#endif /* CONFIG_405EX */
#endif /* CONFIG_PCI */

File diff suppressed because it is too large Load Diff

View File

@ -1,267 +0,0 @@
/*
* (C) Copyright 2000-2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2010
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* SPDX-License-Identifier: GPL-2.0 IBM-pibs
*/
#include <common.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <watchdog.h>
#include <asm/ppc4xx.h>
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_405GP) || \
defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
defined(CONFIG_405EX) || defined(CONFIG_440)
#if defined(CONFIG_440)
#if defined(CONFIG_440GP)
#define CR0_MASK 0x3fff0000
#define CR0_EXTCLK_ENA 0x00600000
#define CR0_UDIV_POS 16
#define UDIV_SUBTRACT 1
#define UART0_SDR CPC0_CR0
#define MFREG(a, d) d = mfdcr(a)
#define MTREG(a, d) mtdcr(a, d)
#else /* #if defined(CONFIG_440GP) */
/* all other 440 PPC's access clock divider via sdr register */
#define CR0_MASK 0xdfffffff
#define CR0_EXTCLK_ENA 0x00800000
#define CR0_UDIV_POS 0
#define UDIV_SUBTRACT 0
#define UART0_SDR SDR0_UART0
#define UART1_SDR SDR0_UART1
#if defined(CONFIG_440EP) || defined(CONFIG_440EPX) || \
defined(CONFIG_440GR) || defined(CONFIG_440GRX) || \
defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
#define UART2_SDR SDR0_UART2
#endif
#if defined(CONFIG_440EP) || defined(CONFIG_440EPX) || \
defined(CONFIG_440GR) || defined(CONFIG_440GRX) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
#define UART3_SDR SDR0_UART3
#endif
#define MFREG(a, d) mfsdr(a, d)
#define MTREG(a, d) mtsdr(a, d)
#endif /* #if defined(CONFIG_440GP) */
#elif defined(CONFIG_405EP) || defined(CONFIG_405EZ)
#define UCR0_MASK 0x0000007f
#define UCR1_MASK 0x00007f00
#define UCR0_UDIV_POS 0
#define UCR1_UDIV_POS 8
#define UDIV_MAX 127
#elif defined(CONFIG_405EX)
#define MFREG(a, d) mfsdr(a, d)
#define MTREG(a, d) mtsdr(a, d)
#define CR0_MASK 0x000000ff
#define CR0_EXTCLK_ENA 0x00800000
#define CR0_UDIV_POS 0
#define UDIV_SUBTRACT 0
#define UART0_SDR SDR0_UART0
#define UART1_SDR SDR0_UART1
#else /* CONFIG_405GP */
#define CR0_MASK 0x00001fff
#define CR0_EXTCLK_ENA 0x000000c0
#define CR0_UDIV_POS 1
#define UDIV_MAX 32
#endif
#if defined(CONFIG_405EP) && defined(CONFIG_SYS_EXT_SERIAL_CLOCK)
#error "External serial clock not supported on AMCC PPC405EP!"
#endif
#if (defined(CONFIG_405EX) || defined(CONFIG_405EZ) || \
defined(CONFIG_440)) && !defined(CONFIG_SYS_EXT_SERIAL_CLOCK)
/*
* For some SoC's, the cpu clock is on divider chain A, UART on
* divider chain B ... so cpu clock is irrelevant. Get the
* "optimized" values that are subject to the 1/2 opb clock
* constraint.
*/
static u16 serial_bdiv(int baudrate, u32 *udiv)
{
sys_info_t sysinfo;
u32 div; /* total divisor udiv * bdiv */
u32 umin; /* minimum udiv */
u16 diff; /* smallest diff */
u16 idiff; /* current diff */
u16 ibdiv; /* current bdiv */
u32 i;
u32 est; /* current estimate */
u32 max;
#if defined(CONFIG_405EZ)
u32 cpr_pllc;
u32 plloutb;
u32 reg;
#endif
get_sys_info(&sysinfo);
#if defined(CONFIG_405EZ)
/* check the pll feedback source */
mfcpr(CPR0_PLLC, cpr_pllc);
plloutb = ((CONFIG_SYS_CLK_FREQ * ((cpr_pllc & PLLC_SRC_MASK) ?
sysinfo.pllFwdDivB : sysinfo.pllFwdDiv) *
sysinfo.pllFbkDiv) / sysinfo.pllFwdDivB);
div = plloutb / (16 * baudrate); /* total divisor */
umin = (plloutb / get_OPB_freq()) << 1; /* 2 x OPB divisor */
max = 256; /* highest possible */
#else /* 405EZ */
div = sysinfo.freqPLB / (16 * baudrate); /* total divisor */
umin = sysinfo.pllOpbDiv << 1; /* 2 x OPB divisor */
max = 32; /* highest possible */
#endif /* 405EZ */
*udiv = diff = max;
/*
* i is the test udiv value -- start with the largest
* possible (max) to minimize serial clock and constrain
* search to umin.
*/
for (i = max; i > umin; i--) {
ibdiv = div / i;
est = i * ibdiv;
idiff = (est > div) ? (est - div) : (div - est);
if (idiff == 0) {
*udiv = i;
break; /* can't do better */
} else if (idiff < diff) {
*udiv = i; /* best so far */
diff = idiff; /* update lowest diff*/
}
}
#if defined(CONFIG_405EZ)
mfcpr(CPR0_PERD0, reg);
reg &= ~0x0000ffff;
reg |= ((*udiv - 0) << 8) | (*udiv - 0);
mtcpr(CPR0_PERD0, reg);
#endif
return div / *udiv;
}
#endif /* #if (defined(CONFIG_405EP) ... */
/*
* This function returns the UART clock used by the common
* NS16550 driver. Additionally the SoC internal divisors for
* optimal UART baudrate are configured.
*/
int get_serial_clock(void)
{
u32 clk;
u32 udiv;
#if !defined(CONFIG_405EZ)
u32 reg;
#endif
#if !defined(CONFIG_SYS_EXT_SERIAL_CLOCK)
PPC4xx_SYS_INFO sys_info;
#endif
/*
* Programming of the internal divisors is SoC specific.
* Let's handle this in some #ifdef's for the SoC's.
*/
#if defined(CONFIG_405GP)
reg = mfdcr(CPC0_CR0) & ~CR0_MASK;
#ifdef CONFIG_SYS_EXT_SERIAL_CLOCK
clk = CONFIG_SYS_EXT_SERIAL_CLOCK;
udiv = 1;
reg |= CR0_EXTCLK_ENA;
#else /* CONFIG_SYS_EXT_SERIAL_CLOCK */
clk = gd->cpu_clk;
#ifdef CONFIG_SYS_405_UART_ERRATA_59
udiv = 31; /* Errata 59: stuck at 31 */
#else /* CONFIG_SYS_405_UART_ERRATA_59 */
{
u32 tmp = CONFIG_SYS_BASE_BAUD * 16;
udiv = (clk + tmp / 2) / tmp;
}
if (udiv > UDIV_MAX) /* max. n bits for udiv */
udiv = UDIV_MAX;
#endif /* CONFIG_SYS_405_UART_ERRATA_59 */
#endif /* CONFIG_SYS_EXT_SERIAL_CLOCK */
reg |= (udiv - 1) << CR0_UDIV_POS; /* set the UART divisor */
mtdcr (CPC0_CR0, reg);
#ifdef CONFIG_SYS_EXT_SERIAL_CLOCK
clk = CONFIG_SYS_EXT_SERIAL_CLOCK;
#else
clk = CONFIG_SYS_BASE_BAUD * 16;
#endif
#endif
#if defined(CONFIG_405EP)
{
u32 tmp = CONFIG_SYS_BASE_BAUD * 16;
reg = mfdcr(CPC0_UCR) & ~(UCR0_MASK | UCR1_MASK);
clk = gd->cpu_clk;
udiv = (clk + tmp / 2) / tmp;
if (udiv > UDIV_MAX) /* max. n bits for udiv */
udiv = UDIV_MAX;
}
reg |= udiv << UCR0_UDIV_POS; /* set the UART divisor */
reg |= udiv << UCR1_UDIV_POS; /* set the UART divisor */
mtdcr(CPC0_UCR, reg);
clk = CONFIG_SYS_BASE_BAUD * 16;
#endif /* CONFIG_405EP */
#if defined(CONFIG_405EX) || defined(CONFIG_440)
MFREG(UART0_SDR, reg);
reg &= ~CR0_MASK;
#ifdef CONFIG_SYS_EXT_SERIAL_CLOCK
reg |= CR0_EXTCLK_ENA;
udiv = 1;
clk = CONFIG_SYS_EXT_SERIAL_CLOCK;
#else /* CONFIG_SYS_EXT_SERIAL_CLOCK */
clk = gd->baudrate * serial_bdiv(gd->baudrate, &udiv) * 16;
#endif /* CONFIG_SYS_EXT_SERIAL_CLOCK */
reg |= (udiv - UDIV_SUBTRACT) << CR0_UDIV_POS; /* set the UART divisor */
/*
* Configure input clock to baudrate generator for all
* available serial ports here
*/
MTREG(UART0_SDR, reg);
#if defined(UART1_SDR)
MTREG(UART1_SDR, reg);
#endif
#if defined(UART2_SDR)
MTREG(UART2_SDR, reg);
#endif
#if defined(UART3_SDR)
MTREG(UART3_SDR, reg);
#endif
#endif /* CONFIG_405EX ... */
#if defined(CONFIG_405EZ)
clk = gd->baudrate * serial_bdiv(gd->baudrate, &udiv) * 16;
#endif /* CONFIG_405EZ */
/*
* Correct UART frequency in bd-info struct now that
* the UART divisor is available
*/
#ifdef CONFIG_SYS_EXT_SERIAL_CLOCK
gd->arch.uart_clk = CONFIG_SYS_EXT_SERIAL_CLOCK;
#else
get_sys_info(&sys_info);
gd->arch.uart_clk = sys_info.freqUART / udiv;
#endif
return clk;
}
#endif /* CONFIG_405GP */

View File

@ -1,179 +0,0 @@
menu "ppc4xx CPU"
depends on 4xx
config SYS_CPU
default "ppc4xx"
choice
prompt "Target select"
optional
config TARGET_LWMON5
bool "Support lwmon5"
config TARGET_T3CORP
bool "Support t3corp"
config TARGET_ACADIA
bool "Support acadia"
config TARGET_BAMBOO
bool "Support bamboo"
config TARGET_BUBINGA
bool "Support bubinga"
config TARGET_CANYONLANDS
bool "Support canyonlands"
select DM
select DM_SERIAL
config TARGET_KATMAI
bool "Support katmai"
select PHYS_64BIT
config TARGET_KILAUEA
bool "Support kilauea"
config TARGET_LUAN
bool "Support luan"
config TARGET_MAKALU
bool "Support makalu"
config TARGET_REDWOOD
bool "Support redwood"
config TARGET_SEQUOIA
bool "Support sequoia"
config TARGET_WALNUT
bool "Support walnut"
config TARGET_YOSEMITE
bool "Support yosemite"
config TARGET_YUCCA
bool "Support yucca"
config TARGET_CPCI2DP
bool "Support CPCI2DP"
config TARGET_CPCI4052
bool "Support CPCI4052"
config TARGET_PLU405
bool "Support PLU405"
config TARGET_PMC405DE
bool "Support PMC405DE"
config TARGET_PMC440
bool "Support PMC440"
config TARGET_VOM405
bool "Support VOM405"
config TARGET_DLVISION_10G
bool "Support dlvision-10g"
config TARGET_IO
bool "Support io"
config TARGET_IOCON
bool "Support iocon"
config TARGET_NEO
bool "Support neo"
config TARGET_IO64
bool "Support io64"
config TARGET_DLVISION
bool "Support dlvision"
config TARGET_GDPPC440ETX
bool "Support gdppc440etx"
config TARGET_INTIP
bool "Support intip"
config TARGET_ICON
bool "Support icon"
config TARGET_MIP405
bool "Support MIP405"
config TARGET_MIP405T
bool "Support MIP405T"
config TARGET_PIP405
bool "Support PIP405"
config TARGET_XPEDITE1000
bool "Support xpedite1000"
config TARGET_XILINX_PPC405_GENERIC
bool "Support xilinx-ppc405-generic"
select SUPPORT_SPL
select OF_CONTROL
select DM
select DM_SERIAL
config TARGET_XILINX_PPC440_GENERIC
bool "Support xilinx-ppc440-generic"
select SUPPORT_SPL
select OF_CONTROL
select DM
select DM_SERIAL
endchoice
config CMD_CHIP_CONFIG
bool "Enable the 'chip_config' command"
help
This command programs the I2C bootstrap EEPROM or shows a list of
possible configurations. The configurations are board-specific
and control the CPU and peripehrals clocks. The programmed
configuration is then used when the board boots.
config CMD_ECCTEST
bool "Enable the 'ecctest' command"
help
This command tests memory ECC by single and double error bit
injection.
source "board/amcc/acadia/Kconfig"
source "board/amcc/bamboo/Kconfig"
source "board/amcc/bubinga/Kconfig"
source "board/amcc/canyonlands/Kconfig"
source "board/amcc/katmai/Kconfig"
source "board/amcc/kilauea/Kconfig"
source "board/amcc/luan/Kconfig"
source "board/amcc/makalu/Kconfig"
source "board/amcc/redwood/Kconfig"
source "board/amcc/sequoia/Kconfig"
source "board/amcc/walnut/Kconfig"
source "board/amcc/yosemite/Kconfig"
source "board/amcc/yucca/Kconfig"
source "board/esd/cpci2dp/Kconfig"
source "board/esd/cpci405/Kconfig"
source "board/esd/plu405/Kconfig"
source "board/esd/pmc405de/Kconfig"
source "board/esd/pmc440/Kconfig"
source "board/esd/vom405/Kconfig"
source "board/gdsys/405ep/Kconfig"
source "board/gdsys/405ex/Kconfig"
source "board/gdsys/dlvision/Kconfig"
source "board/gdsys/gdppc440etx/Kconfig"
source "board/gdsys/intip/Kconfig"
source "board/liebherr/lwmon5/Kconfig"
source "board/mosaixtech/icon/Kconfig"
source "board/mpl/mip405/Kconfig"
source "board/mpl/pip405/Kconfig"
source "board/t3corp/Kconfig"
source "board/xes/xpedite1000/Kconfig"
source "board/xilinx/ppc405-generic/Kconfig"
source "board/xilinx/ppc440-generic/Kconfig"
endmenu

View File

@ -1,49 +0,0 @@
#
# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
extra-y := resetvec.o
extra-y += start.o
obj-y := cache.o
obj-y += dcr.o
obj-y += kgdb.o
obj-y += 40x_spd_sdram.o
obj-y += 44x_spd_ddr.o
obj-$(CONFIG_SDRAM_PPC4xx_IBM_DDR2) += 44x_spd_ddr2.o
obj-$(CONFIG_PPC4xx_DDR_AUTOCALIBRATION) += 4xx_ibm_ddr2_autocalib.o
obj-y += 4xx_pci.o
obj-y += 4xx_pcie.o
obj-y += bedbug_405.o
obj-$(CONFIG_CMD_CHIP_CONFIG) += cmd_chip_config.o
obj-y += cpu.o
obj-y += cpu_init.o
obj-y += denali_data_eye.o
obj-y += denali_spd_ddr2.o
obj-y += ecc.o
obj-$(CONFIG_CMD_ECCTEST) += cmd_ecctest.o
obj-y += fdt.o
obj-y += interrupts.o
obj-$(CONFIG_CMD_REGINFO) += reginfo.o
obj-y += sdram.o
obj-y += speed.o
obj-y += tlb.o
obj-y += traps.o
obj-y += usb.o
obj-y += usb_ohci.o
obj-$(CONFIG_XILINX_440) += xilinx_irq.o
ifndef CONFIG_XILINX_440
obj-y += 4xx_uart.o
obj-y += gpio.o
obj-y += miiphy.o
obj-y += uic.o
endif
ifdef CONFIG_SPL_BUILD
obj-y += spl_boot.o
endif

View File

@ -1,308 +0,0 @@
/*
* Bedbug Functions specific to the PPC405 chip
*/
#include <common.h>
#include <command.h>
#include <linux/ctype.h>
#include <bedbug/type.h>
#include <bedbug/bedbug.h>
#include <bedbug/regs.h>
#include <bedbug/ppc.h>
#if defined(CONFIG_CMD_BEDBUG) && defined(CONFIG_4xx)
#define MAX_BREAK_POINTS 4
extern CPU_DEBUG_CTX bug_ctx;
void bedbug405_init __P ((void));
void bedbug405_do_break __P ((cmd_tbl_t *, int, int, char * const []));
void bedbug405_break_isr __P ((struct pt_regs *));
int bedbug405_find_empty __P ((void));
int bedbug405_set __P ((int, unsigned long));
int bedbug405_clear __P ((int));
/* ======================================================================
* Initialize the global bug_ctx structure for the AMCC PPC405. Clear all
* of the breakpoints.
* ====================================================================== */
void bedbug405_init (void)
{
int i;
/* -------------------------------------------------- */
bug_ctx.hw_debug_enabled = 0;
bug_ctx.stopped = 0;
bug_ctx.current_bp = 0;
bug_ctx.regs = NULL;
bug_ctx.do_break = bedbug405_do_break;
bug_ctx.break_isr = bedbug405_break_isr;
bug_ctx.find_empty = bedbug405_find_empty;
bug_ctx.set = bedbug405_set;
bug_ctx.clear = bedbug405_clear;
for (i = 1; i <= MAX_BREAK_POINTS; ++i)
(*bug_ctx.clear) (i);
puts ("BEDBUG:ready\n");
return;
} /* bedbug_init_breakpoints */
/* ======================================================================
* Set/clear/show one of the hardware breakpoints for the 405. The "off"
* string will disable a specific breakpoint. The "show" string will
* display the current breakpoints. Otherwise an address will set a
* breakpoint at that address. Setting a breakpoint uses the CPU-specific
* set routine which will assign a breakpoint number.
* ====================================================================== */
void bedbug405_do_break (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
long addr = 0; /* Address to break at */
int which_bp; /* Breakpoint number */
/* -------------------------------------------------- */
if (argc < 2) {
cmd_usage(cmdtp);
return;
}
/* Turn off a breakpoint */
if (strcmp (argv[1], "off") == 0) {
if (bug_ctx.hw_debug_enabled == 0) {
printf ("No breakpoints enabled\n");
return;
}
which_bp = simple_strtoul (argv[2], NULL, 10);
if (bug_ctx.clear)
(*bug_ctx.clear) (which_bp);
printf ("Breakpoint %d removed\n", which_bp);
return;
}
/* Show a list of breakpoints */
if (strcmp (argv[1], "show") == 0) {
for (which_bp = 1; which_bp <= MAX_BREAK_POINTS; ++which_bp) {
switch (which_bp) {
case 1:
addr = GET_IAC1 ();
break;
case 2:
addr = GET_IAC2 ();
break;
case 3:
addr = GET_IAC3 ();
break;
case 4:
addr = GET_IAC4 ();
break;
}
printf ("Breakpoint [%d]: ", which_bp);
if (addr == 0)
printf ("NOT SET\n");
else
disppc ((unsigned char *) addr, 0, 1, bedbug_puts,
F_RADHEX);
}
return;
}
/* Set a breakpoint at the address */
if (!isdigit (argv[1][0])) {
cmd_usage(cmdtp);
return;
}
addr = simple_strtoul (argv[1], NULL, 16) & 0xfffffffc;
if ((bug_ctx.set) && (which_bp = (*bug_ctx.set) (0, addr)) > 0) {
printf ("Breakpoint [%d]: ", which_bp);
disppc ((unsigned char *) addr, 0, 1, bedbug_puts, F_RADHEX);
}
return;
} /* bedbug405_do_break */
/* ======================================================================
* Handle a breakpoint. First determine which breakpoint was hit by
* looking at the DeBug Status Register (DBSR), clear the breakpoint
* and enter a mini main loop. Stay in the loop until the stopped flag
* in the debug context is cleared.
* ====================================================================== */
void bedbug405_break_isr (struct pt_regs *regs)
{
unsigned long dbsr_val; /* Value of the DBSR */
unsigned long addr = 0; /* Address stopped at */
/* -------------------------------------------------- */
dbsr_val = GET_DBSR ();
if (dbsr_val & DBSR_IA1) {
bug_ctx.current_bp = 1;
addr = GET_IAC1 ();
SET_DBSR (DBSR_IA1); /* Write a 1 to clear */
} else if (dbsr_val & DBSR_IA2) {
bug_ctx.current_bp = 2;
addr = GET_IAC2 ();
SET_DBSR (DBSR_IA2); /* Write a 1 to clear */
} else if (dbsr_val & DBSR_IA3) {
bug_ctx.current_bp = 3;
addr = GET_IAC3 ();
SET_DBSR (DBSR_IA3); /* Write a 1 to clear */
} else if (dbsr_val & DBSR_IA4) {
bug_ctx.current_bp = 4;
addr = GET_IAC4 ();
SET_DBSR (DBSR_IA4); /* Write a 1 to clear */
}
bedbug_main_loop (addr, regs);
return;
} /* bedbug405_break_isr */
/* ======================================================================
* Look through all of the hardware breakpoints available to see if one
* is unused.
* ====================================================================== */
int bedbug405_find_empty (void)
{
/* -------------------------------------------------- */
if (GET_IAC1 () == 0)
return 1;
if (GET_IAC2 () == 0)
return 2;
if (GET_IAC3 () == 0)
return 3;
if (GET_IAC4 () == 0)
return 4;
return 0;
} /* bedbug405_find_empty */
/* ======================================================================
* Set a breakpoint. If 'which_bp' is zero then find an unused breakpoint
* number, otherwise reassign the given breakpoint. If hardware debugging
* is not enabled, then turn it on via the MSR and DBCR0. Set the break
* address in the appropriate IACx register and enable proper address
* beakpoint in DBCR0.
* ====================================================================== */
int bedbug405_set (int which_bp, unsigned long addr)
{
/* -------------------------------------------------- */
/* Only look if which_bp == 0, else use which_bp */
if ((bug_ctx.find_empty) && (!which_bp) &&
(which_bp = (*bug_ctx.find_empty) ()) == 0) {
printf ("All breakpoints in use\n");
return 0;
}
if (which_bp < 1 || which_bp > MAX_BREAK_POINTS) {
printf ("Invalid break point # %d\n", which_bp);
return 0;
}
if (!bug_ctx.hw_debug_enabled) {
SET_MSR (GET_MSR () | 0x200); /* set MSR[ DE ] */
SET_DBCR0 (GET_DBCR0 () | DBCR0_IDM);
bug_ctx.hw_debug_enabled = 1;
}
switch (which_bp) {
case 1:
SET_IAC1 (addr);
SET_DBCR0 (GET_DBCR0 () | DBCR0_IA1);
break;
case 2:
SET_IAC2 (addr);
SET_DBCR0 (GET_DBCR0 () | DBCR0_IA2);
break;
case 3:
SET_IAC3 (addr);
SET_DBCR0 (GET_DBCR0 () | DBCR0_IA3);
break;
case 4:
SET_IAC4 (addr);
SET_DBCR0 (GET_DBCR0 () | DBCR0_IA4);
break;
}
return which_bp;
} /* bedbug405_set */
/* ======================================================================
* Disable a specific breakoint by setting the appropriate IACx register
* to zero and claring the instruction address breakpoint in DBCR0.
* ====================================================================== */
int bedbug405_clear (int which_bp)
{
/* -------------------------------------------------- */
if (which_bp < 1 || which_bp > MAX_BREAK_POINTS) {
printf ("Invalid break point # (%d)\n", which_bp);
return -1;
}
switch (which_bp) {
case 1:
SET_IAC1 (0);
SET_DBCR0 (GET_DBCR0 () & ~DBCR0_IA1);
break;
case 2:
SET_IAC2 (0);
SET_DBCR0 (GET_DBCR0 () & ~DBCR0_IA2);
break;
case 3:
SET_IAC3 (0);
SET_DBCR0 (GET_DBCR0 () & ~DBCR0_IA3);
break;
case 4:
SET_IAC4 (0);
SET_DBCR0 (GET_DBCR0 () & ~DBCR0_IA4);
break;
}
return 0;
} /* bedbug405_clear */
/* ====================================================================== */
#endif

View File

@ -1,188 +0,0 @@
/*
* This file contains miscellaneous low-level functions.
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
* and Paul Mackerras.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
#include <config.h>
#include <asm/ppc4xx.h>
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
/*
* Flush instruction cache.
*/
_GLOBAL(invalidate_icache)
iccci r0,r0
isync
blr
/*
* Write any modified data cache blocks out to memory
* and invalidate the corresponding instruction cache blocks.
*
* flush_icache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(flush_icache_range)
li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
mr r6,r3
1: dcbst 0,r3
addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbst's to get to ram */
mtctr r4
2: icbi 0,r6
addi r6,r6,L1_CACHE_BYTES
bdnz 2b
sync /* additional sync needed on g4 */
isync
blr
/*
* Write any modified data cache blocks out to memory.
* Does not invalidate the corresponding cache lines (especially for
* any corresponding instruction cache).
*
* clean_dcache_range(unsigned long start, unsigned long stop)
*/
_GLOBAL(clean_dcache_range)
li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
1: dcbst 0,r3
addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbst's to get to ram */
blr
/*
* 40x cores have 8K or 16K dcache and 32 byte line size.
* 44x has a 32K dcache and 32 byte line size.
* 8xx has 1, 2, 4, 8K variants.
* For now, cover the worst case of the 44x.
* Must be called with external interrupts disabled.
*/
#define CACHE_NWAYS 64
#define CACHE_NLINES 32
_GLOBAL(flush_dcache)
li r4,(2 * CACHE_NWAYS * CACHE_NLINES)
mtctr r4
lis r5,0
1: lwz r3,0(r5) /* Load one word from every line */
addi r5,r5,L1_CACHE_BYTES
bdnz 1b
sync
blr
_GLOBAL(invalidate_dcache)
addi r6,0,0x0000 /* clear GPR 6 */
/* Do loop for # of dcache congruence classes. */
lis r7,(CONFIG_SYS_DCACHE_SIZE / L1_CACHE_BYTES / 2)@ha /* TBS for large sized cache */
ori r7,r7,(CONFIG_SYS_DCACHE_SIZE / L1_CACHE_BYTES / 2)@l
/* NOTE: dccci invalidates both */
mtctr r7 /* ways in the D cache */
..dcloop:
dccci 0,r6 /* invalidate line */
addi r6,r6,L1_CACHE_BYTES /* bump to next line */
bdnz ..dcloop
sync
blr
/*
* Cache functions.
*
* NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM,
* although for some cache-ralated calls stubs have to be provided to satisfy
* symbols resolution.
* Icache-related functions are used in POST framework.
*
*/
#ifdef CONFIG_440
.globl dcache_disable
.globl dcache_enable
.globl icache_disable
.globl icache_enable
dcache_disable:
dcache_enable:
icache_disable:
icache_enable:
blr
.globl dcache_status
.globl icache_status
dcache_status:
icache_status:
mr r3, 0
blr
#else /* CONFIG_440 */
.globl icache_enable
icache_enable:
mflr r8
bl invalidate_icache
mtlr r8
isync
addis r3,r0, 0xc000 /* set bit 0 */
mticcr r3
blr
.globl icache_disable
icache_disable:
addis r3,r0, 0x0000 /* clear bit 0 */
mticcr r3
isync
blr
.globl icache_status
icache_status:
mficcr r3
srwi r3, r3, 31 /* >>31 => select bit 0 */
blr
.globl dcache_enable
dcache_enable:
mflr r8
bl invalidate_dcache
mtlr r8
isync
addis r3,r0, 0x8000 /* set bit 0 */
mtdccr r3
blr
.globl dcache_disable
dcache_disable:
mflr r8
bl flush_dcache
mtlr r8
addis r3,r0, 0x0000 /* clear bit 0 */
mtdccr r3
blr
.globl dcache_status
dcache_status:
mfdccr r3
srwi r3, r3, 31 /* >>31 => select bit 0 */
blr
#endif /* CONFIG_440 */

View File

@ -1,131 +0,0 @@
/*
* (C) Copyright 2008-2009
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2009
* Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
#include <i2c.h>
#include <asm/ppc4xx_config.h>
#include <asm/io.h>
static void print_configs(int cur_config_nr)
{
int i;
for (i = 0; i < ppc4xx_config_count; i++) {
printf("%-16s - %s", ppc4xx_config_val[i].label,
ppc4xx_config_val[i].description);
if (i == cur_config_nr)
printf(" ***");
printf("\n");
}
}
static int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int i;
int ret;
int cur_config_nr = -1;
u8 cur_config[CONFIG_4xx_CONFIG_BLOCKSIZE];
/*
* First switch to correct I2C bus. This is I2C bus 0
* for all currently available 4xx derivats.
*/
i2c_set_bus_num(0);
#ifdef CONFIG_CMD_EEPROM
ret = eeprom_read(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR,
CONFIG_4xx_CONFIG_I2C_EEPROM_OFFSET,
cur_config, CONFIG_4xx_CONFIG_BLOCKSIZE);
#else
ret = i2c_read(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR,
CONFIG_4xx_CONFIG_I2C_EEPROM_OFFSET,
1, cur_config, CONFIG_4xx_CONFIG_BLOCKSIZE);
#endif
if (ret) {
printf("Error reading EEPROM at addr 0x%x\n",
CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR);
return -1;
}
/*
* Search the current configuration
*/
for (i = 0; i < ppc4xx_config_count; i++) {
if (memcmp(cur_config, ppc4xx_config_val[i].val,
CONFIG_4xx_CONFIG_BLOCKSIZE) == 0)
cur_config_nr = i;
}
if (cur_config_nr == -1) {
printf("Warning: The I2C bootstrap values don't match any"
" of the available options!\n");
printf("I2C bootstrap EEPROM values are (I2C address 0x%02x):\n",
CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR);
for (i = 0; i < CONFIG_4xx_CONFIG_BLOCKSIZE; i++) {
printf("%02x ", cur_config[i]);
}
printf("\n");
}
if (argc < 2) {
printf("Available configurations (I2C address 0x%02x):\n",
CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR);
print_configs(cur_config_nr);
return 0;
}
for (i = 0; i < ppc4xx_config_count; i++) {
/*
* Search for configuration name/label
*/
if (strcmp(argv[1], ppc4xx_config_val[i].label) == 0) {
printf("Using configuration:\n%-16s - %s\n",
ppc4xx_config_val[i].label,
ppc4xx_config_val[i].description);
#ifdef CONFIG_CMD_EEPROM
ret = eeprom_write(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR,
CONFIG_4xx_CONFIG_I2C_EEPROM_OFFSET,
ppc4xx_config_val[i].val,
CONFIG_4xx_CONFIG_BLOCKSIZE);
#else
ret = i2c_write(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR,
CONFIG_4xx_CONFIG_I2C_EEPROM_OFFSET,
1, ppc4xx_config_val[i].val,
CONFIG_4xx_CONFIG_BLOCKSIZE);
#endif
udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
if (ret) {
printf("Error updating EEPROM at addr 0x%x\n",
CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR);
return -1;
}
printf("done (dump via 'i2c md %x 0.1 %x')\n",
CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR,
CONFIG_4xx_CONFIG_BLOCKSIZE);
printf("Reset the board for the changes to"
" take effect\n");
return 0;
}
}
printf("Configuration %s not found!\n", argv[1]);
print_configs(cur_config_nr);
return -1;
}
U_BOOT_CMD(
chip_config, 2, 0, do_chip_config,
"program the I2C bootstrap EEPROM",
"[config-label]"
);

View File

@ -1,262 +0,0 @@
/*
* (C) Copyright 2010
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/ppc4xx.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/cache.h>
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR) || \
defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
#if defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC)
#if defined(CONFIG_405EX)
/*
* Currently only 405EX uses 16bit data bus width as an alternative
* option to 32bit data width (SDRAM0_MCOPT1_WDTH)
*/
#define SDRAM_DATA_ALT_WIDTH 2
#else
#define SDRAM_DATA_ALT_WIDTH 8
#endif
#if defined(CONFIG_SYS_OCM_BASE)
#define CONFIG_FUNC_ISRAM_ADDR CONFIG_SYS_OCM_BASE
#endif
#if defined(CONFIG_SYS_ISRAM_BASE)
#define CONFIG_FUNC_ISRAM_ADDR CONFIG_SYS_ISRAM_BASE
#endif
#if !defined(CONFIG_FUNC_ISRAM_ADDR)
#error "No internal SRAM/OCM provided!"
#endif
#define force_inline inline __attribute__ ((always_inline))
static inline void machine_check_disable(void)
{
mtmsr(mfmsr() & ~MSR_ME);
}
static inline void machine_check_enable(void)
{
mtmsr(mfmsr() | MSR_ME);
}
/*
* These helper functions need to be inlined, since they
* are called from the functions running from internal SRAM.
* SDRAM operation is forbidden at that time, so calling
* functions in SDRAM has to be avoided.
*/
static force_inline void wait_ddr_idle(void)
{
u32 val;
do {
mfsdram(SDRAM_MCSTAT, val);
} while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT);
}
static force_inline void recalibrate_ddr(void)
{
u32 val;
/*
* Rewrite RQDC & RFDC to calibrate again. If this is not
* done, the SDRAM controller is working correctly after
* changing the MCOPT1_MCHK bits.
*/
mfsdram(SDRAM_RQDC, val);
mtsdram(SDRAM_RQDC, val);
mfsdram(SDRAM_RFDC, val);
mtsdram(SDRAM_RFDC, val);
}
static force_inline void set_mcopt1_mchk(u32 bits)
{
u32 val;
wait_ddr_idle();
mfsdram(SDRAM_MCOPT1, val);
mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) | bits);
recalibrate_ddr();
}
/*
* The next 2 functions are copied to internal SRAM/OCM and run
* there. No function calls allowed here. No SDRAM acitivity should
* be done here.
*/
static void inject_ecc_error(void *ptr, int par)
{
/*
* Taken from PPC460EX/EXr/GT users manual (Rev 1.21)
* 22.2.17.13 ECC Diagnostics
*
* Items 1 ... 5 are already done by now, running from RAM
* with ECC enabled
*/
out_be32(ptr, 0x00000000);
in_be32(ptr);
/* 6. Set memory controller to no error checking */
set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_NON);
/* 7. Modify one or two bits for error simulation */
if (par == 1)
out_be32(ptr, in_be32(ptr) ^ 0x00000001);
else
out_be32(ptr, in_be32(ptr) ^ 0x00000003);
/* 8. Wait for SDRAM idle */
in_be32(ptr);
set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_CHK_REP);
/* Wait for SDRAM idle */
wait_ddr_idle();
/* Continue with 9. in calling function... */
}
static void rewrite_ecc_parity(void *ptr, int par)
{
u32 current_address = (u32)ptr;
u32 end_address;
u32 address_increment;
u32 mcopt1;
/*
* Fill ECC parity byte again. Otherwise further accesses to
* the failure address will result in exceptions.
*/
/* Wait for SDRAM idle */
in_be32(0x00000000);
set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_GEN);
/* ECC bit set method for non-cached memory */
mfsdram(SDRAM_MCOPT1, mcopt1);
if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32)
address_increment = 4;
else
address_increment = SDRAM_DATA_ALT_WIDTH;
end_address = current_address + CONFIG_SYS_CACHELINE_SIZE;
while (current_address < end_address) {
*((unsigned long *)current_address) = 0;
current_address += address_increment;
}
set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_CHK_REP);
/* Wait for SDRAM idle */
wait_ddr_idle();
}
static int do_ecctest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
u32 old_val;
u32 val;
u32 *ptr;
void (*sram_func)(u32 *, int);
int error;
if (argc < 3) {
return cmd_usage(cmdtp);
}
ptr = (u32 *)simple_strtoul(argv[1], NULL, 16);
error = simple_strtoul(argv[2], NULL, 16);
if ((error < 1) || (error > 2)) {
return cmd_usage(cmdtp);
}
printf("Using address %p for %d bit ECC error injection\n",
ptr, error);
/*
* Save value to restore it later on
*/
old_val = in_be32(ptr);
/*
* Copy ECC injection function into internal SRAM/OCM
*/
sram_func = (void *)CONFIG_FUNC_ISRAM_ADDR;
memcpy((void *)CONFIG_FUNC_ISRAM_ADDR, inject_ecc_error, 0x10000);
/*
* Disable interrupts and exceptions before calling this
* function in internal SRAM/OCM
*/
disable_interrupts();
machine_check_disable();
eieio();
/*
* Jump to ECC simulation function in internal SRAM/OCM
*/
(*sram_func)(ptr, error);
/* 10. Read the corresponding address */
val = in_be32(ptr);
/*
* Read and print ECC status register/info:
* The faulting address is only known upon uncorrectable ECC
* errors.
*/
mfsdram(SDRAM_ECCES, val);
if (val & SDRAM_ECCES_CE)
printf("ECC: Correctable error\n");
if (val & SDRAM_ECCES_UE) {
printf("ECC: Uncorrectable error at 0x%02x%08x\n",
mfdcr(SDRAM_ERRADDULL), mfdcr(SDRAM_ERRADDLLL));
}
/*
* Clear pending interrupts/exceptions
*/
mtsdram(SDRAM_ECCES, 0xffffffff);
mtdcr(SDRAM_ERRSTATLL, 0xff000000);
set_mcsr(get_mcsr());
/* Now enable interrupts and exceptions again */
eieio();
machine_check_enable();
enable_interrupts();
/*
* The ECC parity byte need to be re-written for the
* corresponding address. Otherwise future accesses to it
* will result in exceptions.
*
* Jump to ECC parity generation function
*/
memcpy((void *)CONFIG_FUNC_ISRAM_ADDR, rewrite_ecc_parity, 0x10000);
(*sram_func)(ptr, 0);
/*
* Restore value in corresponding address
*/
out_be32(ptr, old_val);
return 0;
}
U_BOOT_CMD(
ecctest, 3, 0, do_ecctest,
"Test ECC by single and double error bit injection",
"address 1/2"
);
#endif /* defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC) */
#endif /* defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)... */

View File

@ -1,14 +0,0 @@
#
# (C) Copyright 2000-2010
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
PLATFORM_CPPFLAGS += -mstring -msoft-float
ifneq (,$(CONFIG_440))
PLATFORM_CPPFLAGS += -Wa,-m440 -mcpu=440
else
PLATFORM_CPPFLAGS += -Wa,-m405 -mcpu=405
endif

View File

@ -1,702 +0,0 @@
/*
* (C) Copyright 2000-2007
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*
* CPU specific code
*
* written or collected and sometimes rewritten by
* Magnus Damm <damm@bitsmart.com>
*
* minor modifications by
* Wolfgang Denk <wd@denx.de>
*/
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <asm/cache.h>
#include <asm/ppc4xx.h>
#include <netdev.h>
DECLARE_GLOBAL_DATA_PTR;
void board_reset(void);
/*
* To provide an interface to detect CPU number for boards that support
* more then one CPU, we implement the "weak" default functions here.
*
* Returns CPU number
*/
int __get_cpu_num(void)
{
return NA_OR_UNKNOWN_CPU;
}
int get_cpu_num(void) __attribute__((weak, alias("__get_cpu_num")));
#if defined(CONFIG_PCI)
#if defined(CONFIG_405GP) || \
defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
#define PCI_ASYNC
static int pci_async_enabled(void)
{
#if defined(CONFIG_405GP)
return (mfdcr(CPC0_PSR) & PSR_PCI_ASYNC_EN);
#endif
#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
unsigned long val;
mfsdr(SDR0_SDSTP1, val);
return (val & SDR0_SDSTP1_PAME_MASK);
#endif
}
#endif
#endif /* CONFIG_PCI */
#if defined(CONFIG_PCI) && \
!defined(CONFIG_405) && !defined(CONFIG_405EX)
int pci_arbiter_enabled(void)
{
#if defined(CONFIG_405GP)
return (mfdcr(CPC0_PSR) & PSR_PCI_ARBIT_EN);
#endif
#if defined(CONFIG_405EP)
return (mfdcr(CPC0_PCI) & CPC0_PCI_ARBIT_EN);
#endif
#if defined(CONFIG_440GP)
return (mfdcr(CPC0_STRP1) & CPC0_STRP1_PAE_MASK);
#endif
#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
unsigned long val;
mfsdr(SDR0_XCR0, val);
return (val & SDR0_XCR0_PAE_MASK);
#endif
#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
unsigned long val;
mfsdr(SDR0_PCI0, val);
return (val & SDR0_PCI0_PAE_MASK);
#endif
}
#endif
#if defined(CONFIG_405EP)
#define I2C_BOOTROM
static int i2c_bootrom_enabled(void)
{
#if defined(CONFIG_405EP)
return (mfdcr(CPC0_BOOT) & CPC0_BOOT_SEP);
#else
unsigned long val;
mfsdr(SDR0_SDCS0, val);
return (val & SDR0_SDCS_SDD);
#endif
}
#endif
#if defined(CONFIG_440GX)
#define SDR0_PINSTP_SHIFT 29
static char *bootstrap_str[] = {
"EBC (16 bits)",
"EBC (8 bits)",
"EBC (32 bits)",
"EBC (8 bits)",
"PCI",
"I2C (Addr 0x54)",
"Reserved",
"I2C (Addr 0x50)",
};
static char bootstrap_char[] = { 'A', 'B', 'C', 'B', 'D', 'E', 'x', 'F' };
#endif
#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
#define SDR0_PINSTP_SHIFT 30
static char *bootstrap_str[] = {
"EBC (8 bits)",
"PCI",
"I2C (Addr 0x54)",
"I2C (Addr 0x50)",
};
static char bootstrap_char[] = { 'A', 'B', 'C', 'D'};
#endif
#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
#define SDR0_PINSTP_SHIFT 29
static char *bootstrap_str[] = {
"EBC (8 bits)",
"PCI",
"NAND (8 bits)",
"EBC (16 bits)",
"EBC (16 bits)",
"I2C (Addr 0x54)",
"PCI",
"I2C (Addr 0x52)",
};
static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };
#endif
#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
#define SDR0_PINSTP_SHIFT 29
static char *bootstrap_str[] = {
"EBC (8 bits)",
"EBC (16 bits)",
"EBC (16 bits)",
"NAND (8 bits)",
"PCI",
"I2C (Addr 0x54)",
"PCI",
"I2C (Addr 0x52)",
};
static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };
#endif
#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
#define SDR0_PINSTP_SHIFT 29
static char *bootstrap_str[] = {
"EBC (8 bits)",
"EBC (16 bits)",
"PCI",
"PCI",
"EBC (16 bits)",
"NAND (8 bits)",
"I2C (Addr 0x54)", /* A8 */
"I2C (Addr 0x52)", /* A4 */
};
static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
#endif
#if defined(CONFIG_460SX)
#define SDR0_PINSTP_SHIFT 29
static char *bootstrap_str[] = {
"EBC (8 bits)",
"EBC (16 bits)",
"EBC (32 bits)",
"NAND (8 bits)",
"I2C (Addr 0x54)", /* A8 */
"I2C (Addr 0x52)", /* A4 */
};
static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G' };
#endif
#if defined(CONFIG_405EZ)
#define SDR0_PINSTP_SHIFT 28
static char *bootstrap_str[] = {
"EBC (8 bits)",
"SPI (fast)",
"NAND (512 page, 4 addr cycle)",
"I2C (Addr 0x50)",
"EBC (32 bits)",
"I2C (Addr 0x50)",
"NAND (2K page, 5 addr cycle)",
"I2C (Addr 0x50)",
"EBC (16 bits)",
"Reserved",
"NAND (2K page, 4 addr cycle)",
"I2C (Addr 0x50)",
"NAND (512 page, 3 addr cycle)",
"I2C (Addr 0x50)",
"SPI (slow)",
"I2C (Addr 0x50)",
};
static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', \
'I', 'x', 'K', 'L', 'M', 'N', 'O', 'P' };
#endif
#if defined(CONFIG_405EX)
#define SDR0_PINSTP_SHIFT 29
static char *bootstrap_str[] = {
"EBC (8 bits)",
"EBC (16 bits)",
"EBC (16 bits)",
"NAND (8 bits)",
"NAND (8 bits)",
"I2C (Addr 0x54)",
"EBC (8 bits)",
"I2C (Addr 0x52)",
};
static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };
#endif
#if defined(SDR0_PINSTP_SHIFT)
static int bootstrap_option(void)
{
unsigned long val;
mfsdr(SDR0_PINSTP, val);
return ((val & 0xf0000000) >> SDR0_PINSTP_SHIFT);
}
#endif /* SDR0_PINSTP_SHIFT */
#if defined(CONFIG_440GP)
static int do_chip_reset (unsigned long sys0, unsigned long sys1)
{
/* Changes to CPC0_SYS0 and CPC0_SYS1 require chip
* reset.
*/
mtdcr (CPC0_CR0, mfdcr (CPC0_CR0) | 0x80000000); /* Set SWE */
mtdcr (CPC0_SYS0, sys0);
mtdcr (CPC0_SYS1, sys1);
mtdcr (CPC0_CR0, mfdcr (CPC0_CR0) & ~0x80000000); /* Clr SWE */
mtspr (SPRN_DBCR0, 0x20000000); /* Reset the chip */
return 1;
}
#endif /* CONFIG_440GP */
int checkcpu (void)
{
#if !defined(CONFIG_405) /* not used on Xilinx 405 FPGA implementations */
uint pvr = get_pvr();
ulong clock = gd->cpu_clk;
char buf[32];
#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
u32 reg;
#endif
char addstr[64] = "";
sys_info_t sys_info;
int cpu_num;
cpu_num = get_cpu_num();
if (cpu_num >= 0)
printf("CPU%d: ", cpu_num);
else
puts("CPU: ");
get_sys_info(&sys_info);
#if defined(CONFIG_XILINX_440)
puts("IBM PowerPC ");
#else
puts("AMCC PowerPC ");
#endif
switch (pvr) {
#if !defined(CONFIG_440)
case PVR_405GP_RB:
puts("405GP Rev. B");
break;
case PVR_405GP_RC:
puts("405GP Rev. C");
break;
case PVR_405GP_RD:
puts("405GP Rev. D");
break;
case PVR_405GP_RE:
puts("405GP Rev. E");
break;
case PVR_405GPR_RB:
puts("405GPr Rev. B");
break;
case PVR_405EP_RB:
puts("405EP Rev. B");
break;
case PVR_405EZ_RA:
puts("405EZ Rev. A");
break;
case PVR_405EX1_RA:
puts("405EX Rev. A");
strcpy(addstr, "Security support");
break;
case PVR_405EXR2_RA:
puts("405EXr Rev. A");
strcpy(addstr, "No Security support");
break;
case PVR_405EX1_RC:
puts("405EX Rev. C");
strcpy(addstr, "Security support");
break;
case PVR_405EX2_RC:
puts("405EX Rev. C");
strcpy(addstr, "No Security support");
break;
case PVR_405EXR1_RC:
puts("405EXr Rev. C");
strcpy(addstr, "Security support");
break;
case PVR_405EXR2_RC:
puts("405EXr Rev. C");
strcpy(addstr, "No Security support");
break;
case PVR_405EX1_RD:
puts("405EX Rev. D");
strcpy(addstr, "Security support");
break;
case PVR_405EX2_RD:
puts("405EX Rev. D");
strcpy(addstr, "No Security support");
break;
case PVR_405EXR1_RD:
puts("405EXr Rev. D");
strcpy(addstr, "Security support");
break;
case PVR_405EXR2_RD:
puts("405EXr Rev. D");
strcpy(addstr, "No Security support");
break;
#else /* CONFIG_440 */
#if defined(CONFIG_440GP)
case PVR_440GP_RB:
puts("440GP Rev. B");
/* See errata 1.12: CHIP_4 */
if ((mfdcr(CPC0_SYS0) != mfdcr(CPC0_STRP0)) ||
(mfdcr(CPC0_SYS1) != mfdcr(CPC0_STRP1)) ){
puts ( "\n\t CPC0_SYSx DCRs corrupted. "
"Resetting chip ...\n");
udelay( 1000 * 1000 ); /* Give time for serial buf to clear */
do_chip_reset ( mfdcr(CPC0_STRP0),
mfdcr(CPC0_STRP1) );
}
break;
case PVR_440GP_RC:
puts("440GP Rev. C");
break;
#endif /* CONFIG_440GP */
case PVR_440GX_RA:
puts("440GX Rev. A");
break;
case PVR_440GX_RB:
puts("440GX Rev. B");
break;
case PVR_440GX_RC:
puts("440GX Rev. C");
break;
case PVR_440GX_RF:
puts("440GX Rev. F");
break;
case PVR_440EP_RA:
puts("440EP Rev. A");
break;
#ifdef CONFIG_440EP
case PVR_440EP_RB: /* 440EP rev B and 440GR rev A have same PVR */
puts("440EP Rev. B");
break;
case PVR_440EP_RC: /* 440EP rev C and 440GR rev B have same PVR */
puts("440EP Rev. C");
break;
#endif /* CONFIG_440EP */
#ifdef CONFIG_440GR
case PVR_440GR_RA: /* 440EP rev B and 440GR rev A have same PVR */
puts("440GR Rev. A");
break;
case PVR_440GR_RB: /* 440EP rev C and 440GR rev B have same PVR */
puts("440GR Rev. B");
break;
#endif /* CONFIG_440GR */
#ifdef CONFIG_440EPX
case PVR_440EPX1_RA: /* 440EPx rev A and 440GRx rev A have same PVR */
puts("440EPx Rev. A");
strcpy(addstr, "Security/Kasumi support");
break;
case PVR_440EPX2_RA: /* 440EPx rev A and 440GRx rev A have same PVR */
puts("440EPx Rev. A");
strcpy(addstr, "No Security/Kasumi support");
break;
#endif /* CONFIG_440EPX */
#ifdef CONFIG_440GRX
case PVR_440GRX1_RA: /* 440EPx rev A and 440GRx rev A have same PVR */
puts("440GRx Rev. A");
strcpy(addstr, "Security/Kasumi support");
break;
case PVR_440GRX2_RA: /* 440EPx rev A and 440GRx rev A have same PVR */
puts("440GRx Rev. A");
strcpy(addstr, "No Security/Kasumi support");
break;
#endif /* CONFIG_440GRX */
case PVR_440SP_6_RAB:
puts("440SP Rev. A/B");
strcpy(addstr, "RAID 6 support");
break;
case PVR_440SP_RAB:
puts("440SP Rev. A/B");
strcpy(addstr, "No RAID 6 support");
break;
case PVR_440SP_6_RC:
puts("440SP Rev. C");
strcpy(addstr, "RAID 6 support");
break;
case PVR_440SP_RC:
puts("440SP Rev. C");
strcpy(addstr, "No RAID 6 support");
break;
case PVR_440SPe_6_RA:
puts("440SPe Rev. A");
strcpy(addstr, "RAID 6 support");
break;
case PVR_440SPe_RA:
puts("440SPe Rev. A");
strcpy(addstr, "No RAID 6 support");
break;
case PVR_440SPe_6_RB:
puts("440SPe Rev. B");
strcpy(addstr, "RAID 6 support");
break;
case PVR_440SPe_RB:
puts("440SPe Rev. B");
strcpy(addstr, "No RAID 6 support");
break;
#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
case PVR_460EX_RA:
puts("460EX Rev. A");
strcpy(addstr, "No Security/Kasumi support");
break;
case PVR_460EX_SE_RA:
puts("460EX Rev. A");
strcpy(addstr, "Security/Kasumi support");
break;
case PVR_460EX_RB:
puts("460EX Rev. B");
mfsdr(SDR0_ECID3, reg);
if (reg & 0x00100000)
strcpy(addstr, "No Security/Kasumi support");
else
strcpy(addstr, "Security/Kasumi support");
break;
case PVR_460GT_RA:
puts("460GT Rev. A");
strcpy(addstr, "No Security/Kasumi support");
break;
case PVR_460GT_SE_RA:
puts("460GT Rev. A");
strcpy(addstr, "Security/Kasumi support");
break;
case PVR_460GT_RB:
puts("460GT Rev. B");
mfsdr(SDR0_ECID3, reg);
if (reg & 0x00100000)
strcpy(addstr, "No Security/Kasumi support");
else
strcpy(addstr, "Security/Kasumi support");
break;
#endif
case PVR_460SX_RA:
puts("460SX Rev. A");
strcpy(addstr, "Security support");
break;
case PVR_460SX_RA_V1:
puts("460SX Rev. A");
strcpy(addstr, "No Security support");
break;
case PVR_460GX_RA:
puts("460GX Rev. A");
strcpy(addstr, "Security support");
break;
case PVR_460GX_RA_V1:
puts("460GX Rev. A");
strcpy(addstr, "No Security support");
break;
case PVR_APM821XX_RA:
puts("APM821XX Rev. A");
strcpy(addstr, "Security support");
break;
case PVR_VIRTEX5:
puts("440x5 VIRTEX5");
break;
#endif /* CONFIG_440 */
default:
printf (" UNKNOWN (PVR=%08x)", pvr);
break;
}
printf (" at %s MHz (PLB=%lu OPB=%lu EBC=%lu",
strmhz(buf, clock),
sys_info.freqPLB / 1000000,
get_OPB_freq() / 1000000,
sys_info.freqEBC / 1000000);
#if defined(CONFIG_PCI) && \
(defined(CONFIG_440EP) || defined(CONFIG_440EPX) || \
defined(CONFIG_440GR) || defined(CONFIG_440GRX))
printf(" PCI=%lu MHz", sys_info.freqPCI / 1000000);
#endif
printf(")\n");
if (addstr[0] != 0)
printf(" %s\n", addstr);
#if defined(I2C_BOOTROM)
printf (" I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis");
#endif /* I2C_BOOTROM */
#if defined(SDR0_PINSTP_SHIFT)
printf (" Bootstrap Option %c - ", bootstrap_char[bootstrap_option()]);
printf ("Boot ROM Location %s", bootstrap_str[bootstrap_option()]);
putc('\n');
#endif /* SDR0_PINSTP_SHIFT */
#if defined(CONFIG_PCI) && !defined(CONFIG_405EX)
printf (" Internal PCI arbiter %sabled", pci_arbiter_enabled() ? "en" : "dis");
#endif
#if defined(CONFIG_PCI) && defined(PCI_ASYNC)
if (pci_async_enabled()) {
printf (", PCI async ext clock used");
} else {
printf (", PCI sync clock at %lu MHz",
sys_info.freqPLB / sys_info.pllPciDiv / 1000000);
}
#endif
#if defined(CONFIG_PCI) && !defined(CONFIG_405EX)
putc('\n');
#endif
#if defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX)
printf(" 16 KiB I-Cache 16 KiB D-Cache");
#elif defined(CONFIG_440)
printf(" 32 KiB I-Cache 32 KiB D-Cache");
#else
printf(" 16 KiB I-Cache %d KiB D-Cache",
((pvr | 0x00000001) == PVR_405GPR_RB) ? 16 : 8);
#endif
#endif /* !defined(CONFIG_405) */
putc ('\n');
return 0;
}
int ppc440spe_revB() {
unsigned int pvr;
pvr = get_pvr();
if ((pvr == PVR_440SPe_6_RB) || (pvr == PVR_440SPe_RB))
return 1;
else
return 0;
}
/* ------------------------------------------------------------------------- */
int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
#if defined(CONFIG_BOARD_RESET)
board_reset();
#else
#if defined(CONFIG_SYS_4xx_RESET_TYPE)
mtspr(SPRN_DBCR0, CONFIG_SYS_4xx_RESET_TYPE << 28);
#else
/*
* Initiate system reset in debug control register DBCR
*/
mtspr(SPRN_DBCR0, 0x30000000);
#endif /* defined(CONFIG_SYS_4xx_RESET_TYPE) */
#endif /* defined(CONFIG_BOARD_RESET) */
return 1;
}
/*
* Get timebase clock frequency
*/
unsigned long get_tbclk (void)
{
sys_info_t sys_info;
get_sys_info(&sys_info);
return (sys_info.freqProcessor);
}
#if defined(CONFIG_WATCHDOG)
void watchdog_reset(void)
{
int re_enable = disable_interrupts();
reset_4xx_watchdog();
if (re_enable) enable_interrupts();
}
void reset_4xx_watchdog(void)
{
/*
* Clear TSR(WIS) bit
*/
mtspr(SPRN_TSR, 0x40000000);
}
#endif /* CONFIG_WATCHDOG */
/*
* Initializes on-chip ethernet controllers.
* to override, implement board_eth_init()
*/
int cpu_eth_init(bd_t *bis)
{
#if defined(CONFIG_PPC4xx_EMAC)
ppc_4xx_eth_initialize(bis);
#endif
return 0;
}

View File

@ -1,541 +0,0 @@
/*
* (C) Copyright 2000-2007
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <watchdog.h>
#include <asm/ppc4xx-emac.h>
#include <asm/processor.h>
#include <asm/ppc4xx-gpio.h>
#include <asm/ppc4xx.h>
DECLARE_GLOBAL_DATA_PTR;
#ifndef CONFIG_SYS_PLL_RECONFIG
#define CONFIG_SYS_PLL_RECONFIG 0
#endif
#if defined(CONFIG_440EPX) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
static void reset_with_rli(void)
{
u32 reg;
/*
* Set reload inhibit so configuration will persist across
* processor resets
*/
mfcpr(CPR0_ICFG, reg);
reg |= CPR0_ICFG_RLI_MASK;
mtcpr(CPR0_ICFG, reg);
/* Reset processor if configuration changed */
__asm__ __volatile__ ("sync; isync");
mtspr(SPRN_DBCR0, 0x20000000);
}
#endif
void reconfigure_pll(u32 new_cpu_freq)
{
#if defined(CONFIG_440EPX)
int reset_needed = 0;
u32 reg, temp;
u32 prbdv0, target_prbdv0, /* CLK_PRIMBD */
fwdva, target_fwdva, fwdvb, target_fwdvb, /* CLK_PLLD */
fbdv, target_fbdv, lfbdv, target_lfbdv,
perdv0, target_perdv0, /* CLK_PERD */
spcid0, target_spcid0; /* CLK_SPCID */
/* Reconfigure clocks if necessary.
* See PPC440EPx User's Manual, sections 8.2 and 14 */
if (new_cpu_freq == 667) {
target_prbdv0 = 2;
target_fwdva = 2;
target_fwdvb = 4;
target_fbdv = 20;
target_lfbdv = 1;
target_perdv0 = 4;
target_spcid0 = 4;
mfcpr(CPR0_PRIMBD0, reg);
temp = (reg & PRBDV_MASK) >> 24;
prbdv0 = temp ? temp : 8;
if (prbdv0 != target_prbdv0) {
reg &= ~PRBDV_MASK;
reg |= ((target_prbdv0 == 8 ? 0 : target_prbdv0) << 24);
mtcpr(CPR0_PRIMBD0, reg);
reset_needed = 1;
}
mfcpr(CPR0_PLLD, reg);
temp = (reg & PLLD_FWDVA_MASK) >> 16;
fwdva = temp ? temp : 16;
temp = (reg & PLLD_FWDVB_MASK) >> 8;
fwdvb = temp ? temp : 8;
temp = (reg & PLLD_FBDV_MASK) >> 24;
fbdv = temp ? temp : 32;
temp = (reg & PLLD_LFBDV_MASK);
lfbdv = temp ? temp : 64;
if (fwdva != target_fwdva || fbdv != target_fbdv || lfbdv != target_lfbdv) {
reg &= ~(PLLD_FWDVA_MASK | PLLD_FWDVB_MASK |
PLLD_FBDV_MASK | PLLD_LFBDV_MASK);
reg |= ((target_fwdva == 16 ? 0 : target_fwdva) << 16) |
((target_fwdvb == 8 ? 0 : target_fwdvb) << 8) |
((target_fbdv == 32 ? 0 : target_fbdv) << 24) |
(target_lfbdv == 64 ? 0 : target_lfbdv);
mtcpr(CPR0_PLLD, reg);
reset_needed = 1;
}
mfcpr(CPR0_PERD, reg);
perdv0 = (reg & CPR0_PERD_PERDV0_MASK) >> 24;
if (perdv0 != target_perdv0) {
reg &= ~CPR0_PERD_PERDV0_MASK;
reg |= (target_perdv0 << 24);
mtcpr(CPR0_PERD, reg);
reset_needed = 1;
}
mfcpr(CPR0_SPCID, reg);
temp = (reg & CPR0_SPCID_SPCIDV0_MASK) >> 24;
spcid0 = temp ? temp : 4;
if (spcid0 != target_spcid0) {
reg &= ~CPR0_SPCID_SPCIDV0_MASK;
reg |= ((target_spcid0 == 4 ? 0 : target_spcid0) << 24);
mtcpr(CPR0_SPCID, reg);
reset_needed = 1;
}
}
/* Get current value of FWDVA.*/
mfcpr(CPR0_PLLD, reg);
temp = (reg & PLLD_FWDVA_MASK) >> 16;
/*
* Check to see if FWDVA has been set to value of 1. if it has we must
* modify it.
*/
if (temp == 1) {
/*
* Load register that contains current boot strapping option.
*/
mfcpr(CPR0_ICFG, reg);
/*
* Strapping option bits (ICS) are already in correct position,
* only masking needed.
*/
reg &= CPR0_ICFG_ICS_MASK;
if ((reg == BOOT_STRAP_OPTION_A) || (reg == BOOT_STRAP_OPTION_B) ||
(reg == BOOT_STRAP_OPTION_D) || (reg == BOOT_STRAP_OPTION_E)) {
mfcpr(CPR0_PLLD, reg);
/* Get current value of fbdv. */
temp = (reg & PLLD_FBDV_MASK) >> 24;
fbdv = temp ? temp : 32;
/* Get current value of lfbdv. */
temp = (reg & PLLD_LFBDV_MASK);
lfbdv = temp ? temp : 64;
/*
* Get current value of FWDVA. Assign current FWDVA to
* new FWDVB.
*/
mfcpr(CPR0_PLLD, reg);
target_fwdvb = (reg & PLLD_FWDVA_MASK) >> 16;
fwdvb = target_fwdvb ? target_fwdvb : 8;
/*
* Get current value of FWDVB. Assign current FWDVB to
* new FWDVA.
*/
target_fwdva = (reg & PLLD_FWDVB_MASK) >> 8;
fwdva = target_fwdva ? target_fwdva : 16;
/*
* Update CPR0_PLLD with switched FWDVA and FWDVB.
*/
reg &= ~(PLLD_FWDVA_MASK | PLLD_FWDVB_MASK |
PLLD_FBDV_MASK | PLLD_LFBDV_MASK);
reg |= ((fwdva == 16 ? 0 : fwdva) << 16) |
((fwdvb == 8 ? 0 : fwdvb) << 8) |
((fbdv == 32 ? 0 : fbdv) << 24) |
(lfbdv == 64 ? 0 : lfbdv);
mtcpr(CPR0_PLLD, reg);
/* Acknowledge that a reset is required. */
reset_needed = 1;
}
}
/* Now reset the CPU if needed */
if (reset_needed)
reset_with_rli();
#endif
#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
u32 reg;
/*
* See "9.2.1.1 Booting with Option E" in the 460EX/GT
* users manual
*/
mfcpr(CPR0_PLLC, reg);
if ((reg & (CPR0_PLLC_RST | CPR0_PLLC_ENG)) == CPR0_PLLC_RST) {
/*
* Set engage bit
*/
reg = (reg & ~CPR0_PLLC_RST) | CPR0_PLLC_ENG;
mtcpr(CPR0_PLLC, reg);
/* Now reset the CPU */
reset_with_rli();
}
#endif
}
#ifdef CONFIG_SYS_4xx_CHIP_21_ERRATA
void
chip_21_errata(void)
{
/*
* See rev 1.09 of the 405EX/405EXr errata. CHIP_21 says that
* sometimes reading the PVR and/or SDR0_ECID results in incorrect
* values. Since the rev-D chip uses the SDR0_ECID bits to control
* internal features, that means the second PCIe or ethernet of an EX
* variant could fail to work. Also, security features of both EX and
* EXr might be incorrectly disabled.
*
* The suggested workaround is as follows (covering rev-C and rev-D):
*
* 1.Read the PVR and SDR0_ECID3.
*
* 2.If the PVR matches an expected Revision C PVR value AND if
* SDR0_ECID3[12:15] is different from PVR[28:31], then processor is
* Revision C: continue executing the initialization code (no reset
* required). else go to step 3.
*
* 3.If the PVR matches an expected Revision D PVR value AND if
* SDR0_ECID3[10:11] matches its expected value, then continue
* executing initialization code, no reset required. else write
* DBCR0[RST] = 0b11 to generate a SysReset.
*/
u32 pvr;
u32 pvr_28_31;
u32 ecid3;
u32 ecid3_10_11;
u32 ecid3_12_15;
/* Step 1: */
pvr = get_pvr();
mfsdr(SDR0_ECID3, ecid3);
/* Step 2: */
pvr_28_31 = pvr & 0xf;
ecid3_10_11 = (ecid3 >> 20) & 0x3;
ecid3_12_15 = (ecid3 >> 16) & 0xf;
if ((pvr == CONFIG_405EX_CHIP21_PVR_REV_C) &&
(pvr_28_31 != ecid3_12_15)) {
/* No reset required. */
return;
}
/* Step 3: */
if ((pvr == CONFIG_405EX_CHIP21_PVR_REV_D) &&
(ecid3_10_11 == CONFIG_405EX_CHIP21_ECID3_REV_D)) {
/* No reset required. */
return;
}
/* Reset required. */
__asm__ __volatile__ ("sync; isync");
mtspr(SPRN_DBCR0, 0x30000000);
}
#endif
/*
* Breath some life into the CPU...
*
* Reconfigure PLL if necessary,
* set up the memory map,
* initialize a bunch of registers
*/
void
cpu_init_f (void)
{
#if defined(CONFIG_WATCHDOG) || defined(CONFIG_440GX) || defined(CONFIG_460EX)
u32 val;
#endif
#ifdef CONFIG_SYS_4xx_CHIP_21_ERRATA
chip_21_errata();
#endif
reconfigure_pll(CONFIG_SYS_PLL_RECONFIG);
#if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) && \
!defined(CONFIG_SYS_4xx_GPIO_TABLE)
/*
* GPIO0 setup (select GPIO or alternate function)
*/
#if defined(CONFIG_SYS_GPIO0_OR)
out32(GPIO0_OR, CONFIG_SYS_GPIO0_OR); /* set initial state of output pins */
#endif
#if defined(CONFIG_SYS_GPIO0_ODR)
out32(GPIO0_ODR, CONFIG_SYS_GPIO0_ODR); /* open-drain select */
#endif
out32(GPIO0_OSRH, CONFIG_SYS_GPIO0_OSRH); /* output select */
out32(GPIO0_OSRL, CONFIG_SYS_GPIO0_OSRL);
out32(GPIO0_ISR1H, CONFIG_SYS_GPIO0_ISR1H); /* input select */
out32(GPIO0_ISR1L, CONFIG_SYS_GPIO0_ISR1L);
out32(GPIO0_TSRH, CONFIG_SYS_GPIO0_TSRH); /* three-state select */
out32(GPIO0_TSRL, CONFIG_SYS_GPIO0_TSRL);
#if defined(CONFIG_SYS_GPIO0_ISR2H)
out32(GPIO0_ISR2H, CONFIG_SYS_GPIO0_ISR2H);
out32(GPIO0_ISR2L, CONFIG_SYS_GPIO0_ISR2L);
#endif
#if defined (CONFIG_SYS_GPIO0_TCR)
out32(GPIO0_TCR, CONFIG_SYS_GPIO0_TCR); /* enable output driver for outputs */
#endif
#endif /* CONFIG_405EP ... && !CONFIG_SYS_4xx_GPIO_TABLE */
#if defined (CONFIG_405EP)
/*
* Set EMAC noise filter bits
*/
mtdcr(CPC0_EPCTL, CPC0_EPCTL_E0NFE | CPC0_EPCTL_E1NFE);
#endif /* CONFIG_405EP */
#if defined(CONFIG_SYS_4xx_GPIO_TABLE)
gpio_set_chip_configuration();
#endif /* CONFIG_SYS_4xx_GPIO_TABLE */
/*
* External Bus Controller (EBC) Setup
*/
#if (defined(CONFIG_SYS_EBC_PB0AP) && defined(CONFIG_SYS_EBC_PB0CR))
#if (defined(CONFIG_405GP) || \
defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
defined(CONFIG_405EX) || defined(CONFIG_405))
/*
* Move the next instructions into icache, since these modify the flash
* we are running from!
*/
asm volatile(" bl 0f" ::: "lr");
asm volatile("0: mflr 3" ::: "r3");
asm volatile(" addi 4, 0, 14" ::: "r4");
asm volatile(" mtctr 4" ::: "ctr");
asm volatile("1: icbt 0, 3");
asm volatile(" addi 3, 3, 32" ::: "r3");
asm volatile(" bdnz 1b" ::: "ctr", "cr0");
asm volatile(" addis 3, 0, 0x0" ::: "r3");
asm volatile(" ori 3, 3, 0xA000" ::: "r3");
asm volatile(" mtctr 3" ::: "ctr");
asm volatile("2: bdnz 2b" ::: "ctr", "cr0");
#endif
mtebc(PB0AP, CONFIG_SYS_EBC_PB0AP);
mtebc(PB0CR, CONFIG_SYS_EBC_PB0CR);
#endif
#if (defined(CONFIG_SYS_EBC_PB1AP) && defined(CONFIG_SYS_EBC_PB1CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 1))
mtebc(PB1AP, CONFIG_SYS_EBC_PB1AP);
mtebc(PB1CR, CONFIG_SYS_EBC_PB1CR);
#endif
#if (defined(CONFIG_SYS_EBC_PB2AP) && defined(CONFIG_SYS_EBC_PB2CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 2))
mtebc(PB2AP, CONFIG_SYS_EBC_PB2AP);
mtebc(PB2CR, CONFIG_SYS_EBC_PB2CR);
#endif
#if (defined(CONFIG_SYS_EBC_PB3AP) && defined(CONFIG_SYS_EBC_PB3CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 3))
mtebc(PB3AP, CONFIG_SYS_EBC_PB3AP);
mtebc(PB3CR, CONFIG_SYS_EBC_PB3CR);
#endif
#if (defined(CONFIG_SYS_EBC_PB4AP) && defined(CONFIG_SYS_EBC_PB4CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 4))
mtebc(PB4AP, CONFIG_SYS_EBC_PB4AP);
mtebc(PB4CR, CONFIG_SYS_EBC_PB4CR);
#endif
#if (defined(CONFIG_SYS_EBC_PB5AP) && defined(CONFIG_SYS_EBC_PB5CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 5))
mtebc(PB5AP, CONFIG_SYS_EBC_PB5AP);
mtebc(PB5CR, CONFIG_SYS_EBC_PB5CR);
#endif
#if (defined(CONFIG_SYS_EBC_PB6AP) && defined(CONFIG_SYS_EBC_PB6CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 6))
mtebc(PB6AP, CONFIG_SYS_EBC_PB6AP);
mtebc(PB6CR, CONFIG_SYS_EBC_PB6CR);
#endif
#if (defined(CONFIG_SYS_EBC_PB7AP) && defined(CONFIG_SYS_EBC_PB7CR) && !(CONFIG_SYS_INIT_DCACHE_CS == 7))
mtebc(PB7AP, CONFIG_SYS_EBC_PB7AP);
mtebc(PB7CR, CONFIG_SYS_EBC_PB7CR);
#endif
#if defined (CONFIG_SYS_EBC_CFG)
mtebc(EBC0_CFG, CONFIG_SYS_EBC_CFG);
#endif
#if defined(CONFIG_WATCHDOG)
val = mfspr(SPRN_TCR);
#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
val |= 0xb8000000; /* generate system reset after 1.34 seconds */
#elif defined(CONFIG_440EPX)
val |= 0xb0000000; /* generate system reset after 1.34 seconds */
#else
val |= 0xf0000000; /* generate system reset after 2.684 seconds */
#endif
#if defined(CONFIG_SYS_4xx_RESET_TYPE)
val &= ~0x30000000; /* clear WRC bits */
val |= CONFIG_SYS_4xx_RESET_TYPE << 28; /* set board specific WRC type */
#endif
mtspr(SPRN_TCR, val);
val = mfspr(SPRN_TSR);
val |= 0x80000000; /* enable watchdog timer */
mtspr(SPRN_TSR, val);
reset_4xx_watchdog();
#endif /* CONFIG_WATCHDOG */
#if defined(CONFIG_440GX)
/* Take the GX out of compatibility mode
* Travis Sawyer, 9 Mar 2004
* NOTE: 440gx user manual inconsistency here
* Compatibility mode and Ethernet Clock select are not
* correct in the manual
*/
mfsdr(SDR0_MFR, val);
val &= ~0x10000000;
mtsdr(SDR0_MFR,val);
#endif /* CONFIG_440GX */
#if defined(CONFIG_460EX)
/*
* Set SDR0_AHB_CFG[A2P_INCR4] (bit 24) and
* clear SDR0_AHB_CFG[A2P_PROT2] (bit 25) for a new 460EX errata
* regarding concurrent use of AHB USB OTG, USB 2.0 host and SATA
*/
mfsdr(SDR0_AHB_CFG, val);
val |= 0x80;
val &= ~0x40;
mtsdr(SDR0_AHB_CFG, val);
mfsdr(SDR0_USB2HOST_CFG, val);
val &= ~0xf00;
val |= 0x400;
mtsdr(SDR0_USB2HOST_CFG, val);
#endif /* CONFIG_460EX */
#if defined(CONFIG_405EX) || \
defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
defined(CONFIG_460SX)
/*
* Set PLB4 arbiter (Segment 0 and 1) to 4 deep pipeline read
*/
mtdcr(PLB4A0_ACR, (mfdcr(PLB4A0_ACR) & ~PLB4Ax_ACR_RDP_MASK) |
PLB4Ax_ACR_RDP_4DEEP);
mtdcr(PLB4A1_ACR, (mfdcr(PLB4A1_ACR) & ~PLB4Ax_ACR_RDP_MASK) |
PLB4Ax_ACR_RDP_4DEEP);
#endif /* CONFIG_440SP/SPE || CONFIG_460EX/GT || CONFIG_405EX */
}
/*
* initialize higher level parts of CPU like time base and timers
*/
int cpu_init_r (void)
{
#if defined(CONFIG_405GP)
uint pvr = get_pvr();
/*
* Set edge conditioning circuitry on PPC405GPr
* for compatibility to existing PPC405GP designs.
*/
if ((pvr & 0xfffffff0) == (PVR_405GPR_RB & 0xfffffff0)) {
mtdcr(CPC0_ECR, 0x60606000);
}
#endif /* defined(CONFIG_405GP) */
return 0;
}
#if defined(CONFIG_PCI) && \
(defined(CONFIG_440EP) || defined(CONFIG_440EPX) || \
defined(CONFIG_440GR) || defined(CONFIG_440GRX))
/*
* 440EP(x)/GR(x) PCI async/sync clocking restriction:
*
* In asynchronous PCI mode, the synchronous PCI clock must meet
* certain requirements. The following equation describes the
* relationship that must be maintained between the asynchronous PCI
* clock and synchronous PCI clock. Select an appropriate PCI:PLB
* ratio to maintain the relationship:
*
* AsyncPCIClk - 1MHz <= SyncPCIclock <= (2 * AsyncPCIClk) - 1MHz
*/
static int ppc4xx_pci_sync_clock_ok(u32 sync, u32 async)
{
if (((async - 1000000) > sync) || (sync > ((2 * async) - 1000000)))
return 0;
else
return 1;
}
int ppc4xx_pci_sync_clock_config(u32 async)
{
sys_info_t sys_info;
u32 sync;
int div;
u32 reg;
u32 spcid_val[] = {
CPR0_SPCID_SPCIDV0_DIV1, CPR0_SPCID_SPCIDV0_DIV2,
CPR0_SPCID_SPCIDV0_DIV3, CPR0_SPCID_SPCIDV0_DIV4 };
get_sys_info(&sys_info);
sync = sys_info.freqPCI;
/*
* First check if the equation above is met
*/
if (!ppc4xx_pci_sync_clock_ok(sync, async)) {
/*
* Reconfigure PCI sync clock to meet the equation.
* Start with highest possible PCI sync frequency
* (divider 1).
*/
for (div = 1; div <= 4; div++) {
sync = sys_info.freqPLB / div;
if (ppc4xx_pci_sync_clock_ok(sync, async))
break;
}
if (div <= 4) {
mtcpr(CPR0_SPCID, spcid_val[div]);
mfcpr(CPR0_ICFG, reg);
reg |= CPR0_ICFG_RLI_MASK;
mtcpr(CPR0_ICFG, reg);
/* do chip reset */
mtspr(SPRN_DBCR0, 0x20000000);
} else {
/* Impossible to configure the PCI sync clock */
return -1;
}
}
return 0;
}
#endif

View File

@ -1,180 +0,0 @@
/*
* (C) Copyright 2001
* Erik Theisen, Wave 7 Optics, etheisen@mindspring.com
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
#if defined(CONFIG_4xx) && defined(CONFIG_CMD_SETGETDCR)
#include <asm/ppc4xx.h>
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#define _ASMLANGUAGE
/*****************************************************************************
*
* XXX - DANGER
* These routines make use of self modifying code. DO NOT CALL THEM
* UNTIL THEY ARE RELOCATED TO RAM. Additionally, I do not
* recommend them for use in anything other than an interactive
* debugging environment. This is mainly due to performance reasons.
*
****************************************************************************/
/*
* static void _create_MFDCR(unsigned short dcrn)
*
* Builds a 'mfdcr' instruction for get_dcr
* function.
*/
.section ".text"
.align 2
.type _create_MFDCR,@function
_create_MFDCR:
/*
* Build up a 'mfdcr' instruction formatted as follows:
*
* OPCD | RT | DCRF | XO | CR |
* ---------------|--------------|--------------|----|
* 0 5 | 6 10 | 11 20 | 21 30 | 31 |
* | | DCRN | | |
* 31 | %r3 | (5..9|0..4) | 323 | 0 |
*
* Where:
* OPCD = opcode - 31
* RT = destination register - %r3 return register
* DCRF = DCRN # with upper and lower halves swapped
* XO = extended opcode - 323
* CR = CR[CR0] NOT undefined - 0
*/
rlwinm r0, r3, 27, 27, 31 /* OPCD = 31 */
rlwinm r3, r3, 5, 22, 26
or r3, r3, r0
slwi r3, r3, 10
oris r3, r3, 0x3e30 /* RT = %r3 */
ori r3, r3, 323 /* XO = 323 */
slwi r3, r3, 1 /* CR = 0 */
mflr r4
stw r3, 0(r4) /* Store instr in get_dcr() */
dcbst r0, r4 /* Make sure val is written out */
sync /* Wait for write to complete */
icbi r0, r4 /* Make sure old instr is dumped */
isync /* Wait for icbi to complete */
blr
.Lfe1: .size _create_MFDCR,.Lfe1-_create_MFDCR
/* end _create_MFDCR() */
/*
* static void _create_MTDCR(unsigned short dcrn, unsigned long value)
*
* Builds a 'mtdcr' instruction for set_dcr
* function.
*/
.section ".text"
.align 2
.type _create_MTDCR,@function
_create_MTDCR:
/*
* Build up a 'mtdcr' instruction formatted as follows:
*
* OPCD | RS | DCRF | XO | CR |
* ---------------|--------------|--------------|----|
* 0 5 | 6 10 | 11 20 | 21 30 | 31 |
* | | DCRN | | |
* 31 | %r3 | (5..9|0..4) | 451 | 0 |
*
* Where:
* OPCD = opcode - 31
* RS = source register - %r4
* DCRF = dest. DCRN # with upper and lower halves swapped
* XO = extended opcode - 451
* CR = CR[CR0] NOT undefined - 0
*/
rlwinm r0, r3, 27, 27, 31 /* OPCD = 31 */
rlwinm r3, r3, 5, 22, 26
or r3, r3, r0
slwi r3, r3, 10
oris r3, r3, 0x3e40 /* RS = %r4 */
ori r3, r3, 451 /* XO = 451 */
slwi r3, r3, 1 /* CR = 0 */
mflr r5
stw r3, 0(r5) /* Store instr in set_dcr() */
dcbst r0, r5 /* Make sure val is written out */
sync /* Wait for write to complete */
icbi r0, r5 /* Make sure old instr is dumped */
isync /* Wait for icbi to complete */
blr
.Lfe2: .size _create_MTDCR,.Lfe2-_create_MTDCR
/* end _create_MTDCR() */
/*
* unsigned long get_dcr(unsigned short dcrn)
*
* Return a given DCR's value.
*/
/* */
/* XXX - This is self modifying code, hence */
/* it is in the data section. */
/* */
.section ".data"
.align 2
.globl get_dcr
.type get_dcr,@function
get_dcr:
mflr r0 /* Get link register */
stwu r1, -32(r1) /* Save back chain and move SP */
stw r0, +36(r1) /* Save link register */
bl _create_MFDCR /* Build following instruction */
/* XXX - we build this instuction up on the fly. */
.long 0 /* Get DCR's value */
lwz r0, +36(r1) /* Get saved link register */
mtlr r0 /* Restore link register */
addi r1, r1, +32 /* Remove frame from stack */
blr /* Return to calling function */
.Lfe3: .size get_dcr,.Lfe3-get_dcr
/* end get_dcr() */
/*
* unsigned void set_dcr(unsigned short dcrn, unsigned long value)
*
* Return a given DCR's value.
*/
/*
* XXX - This is self modifying code, hence
* it is in the data section.
*/
.section ".data"
.align 2
.globl set_dcr
.type set_dcr,@function
set_dcr:
mflr r0 /* Get link register */
stwu r1, -32(r1) /* Save back chain and move SP */
stw r0, +36(r1) /* Save link register */
bl _create_MTDCR /* Build following instruction */
/* XXX - we build this instuction up on the fly. */
.long 0 /* Set DCR's value */
lwz r0, +36(r1) /* Get saved link register */
mtlr r0 /* Restore link register */
addi r1, r1, +32 /* Remove frame from stack */
blr /* Return to calling function */
.Lfe4: .size set_dcr,.Lfe4-set_dcr
/* end set_dcr() */
#endif

View File

@ -1,376 +0,0 @@
/*
* arch/powerpc/cpu/ppc4xx/denali_data_eye.c
* Extracted from board/amcc/sequoia/sdram.c by Larry Johnson <lrj@acm.org>.
*
* (C) Copyright 2006
* Sylvie Gohl, AMCC/IBM, gohl.sylvie@fr.ibm.com
* Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
* Thierry Roman, AMCC/IBM, thierry_roman@fr.ibm.com
* Alain Saurel, AMCC/IBM, alain.saurel@fr.ibm.com
* Robert Snyder, AMCC/IBM, rob.snyder@fr.ibm.com
*
* (C) Copyright 2006-2007
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/* define DEBUG for debugging output (obviously ;-)) */
#if 0
#define DEBUG
#endif
#include <common.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/ppc4xx.h>
#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
/*-----------------------------------------------------------------------------+
* denali_wait_for_dlllock.
+----------------------------------------------------------------------------*/
int denali_wait_for_dlllock(void)
{
u32 val;
int wait;
/* -----------------------------------------------------------+
* Wait for the DCC master delay line to finish calibration
* ----------------------------------------------------------*/
for (wait = 0; wait != 0xffff; ++wait) {
mfsdram(DDR0_17, val);
if (DDR0_17_DLLLOCKREG_DECODE(val)) {
/* dlllockreg bit on */
return 0;
}
}
debug("0x%04x: DDR0_17 Value (dlllockreg bit): 0x%08x\n", wait, val);
debug("Waiting for dlllockreg bit to raise\n");
return -1;
}
#if defined(CONFIG_DDR_DATA_EYE)
#define DDR_DCR_BASE 0x10
#define ddrcfga (DDR_DCR_BASE+0x0) /* DDR configuration address reg */
#define ddrcfgd (DDR_DCR_BASE+0x1) /* DDR configuration data reg */
/*-----------------------------------------------------------------------------+
* wait_for_dram_init_complete.
+----------------------------------------------------------------------------*/
static int wait_for_dram_init_complete(void)
{
unsigned long val;
int wait = 0;
/* --------------------------------------------------------------+
* Wait for 'DRAM initialization complete' bit in status register
* -------------------------------------------------------------*/
mtdcr(ddrcfga, DDR0_00);
while (wait != 0xffff) {
val = mfdcr(ddrcfgd);
if ((val & DDR0_00_INT_STATUS_BIT6) == DDR0_00_INT_STATUS_BIT6)
/* 'DRAM initialization complete' bit */
return 0;
else
wait++;
}
debug("DRAM initialization complete bit in status register did not "
"rise\n");
return -1;
}
#define NUM_TRIES 64
#define NUM_READS 10
/*-----------------------------------------------------------------------------+
* denali_core_search_data_eye.
+----------------------------------------------------------------------------*/
void denali_core_search_data_eye(void)
{
int k, j;
u32 val;
u32 wr_dqs_shift, dqs_out_shift, dll_dqs_delay_X;
u32 max_passing_cases = 0, wr_dqs_shift_with_max_passing_cases = 0;
u32 passing_cases = 0, dll_dqs_delay_X_sw_val = 0;
u32 dll_dqs_delay_X_start_window = 0, dll_dqs_delay_X_end_window = 0;
volatile u32 *ram_pointer;
u32 test[NUM_TRIES] = {
0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55
};
ram_pointer = (volatile u32 *)(CONFIG_SYS_SDRAM_BASE);
for (wr_dqs_shift = 64; wr_dqs_shift < 96; wr_dqs_shift++) {
/* for (wr_dqs_shift=1; wr_dqs_shift<96; wr_dqs_shift++) { */
/* -----------------------------------------------------------+
* De-assert 'start' parameter.
* ----------------------------------------------------------*/
mtdcr(ddrcfga, DDR0_02);
val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
DDR0_02_START_OFF;
mtdcr(ddrcfgd, val);
/* -----------------------------------------------------------+
* Set 'wr_dqs_shift'
* ----------------------------------------------------------*/
mtdcr(ddrcfga, DDR0_09);
val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK) |
DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
mtdcr(ddrcfgd, val);
/* -----------------------------------------------------------+
* Set 'dqs_out_shift' = wr_dqs_shift + 32
* ----------------------------------------------------------*/
dqs_out_shift = wr_dqs_shift + 32;
mtdcr(ddrcfga, DDR0_22);
val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK) |
DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
mtdcr(ddrcfgd, val);
passing_cases = 0;
for (dll_dqs_delay_X = 1; dll_dqs_delay_X < 64;
dll_dqs_delay_X++) {
/* for (dll_dqs_delay_X=1; dll_dqs_delay_X<128;
dll_dqs_delay_X++) { */
/* -----------------------------------------------------------+
* Set 'dll_dqs_delay_X'.
* ----------------------------------------------------------*/
/* dll_dqs_delay_0 */
mtdcr(ddrcfga, DDR0_17);
val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
| DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
mtdcr(ddrcfgd, val);
/* dll_dqs_delay_1 to dll_dqs_delay_4 */
mtdcr(ddrcfga, DDR0_18);
val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
| DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
| DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
| DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
| DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
mtdcr(ddrcfgd, val);
/* dll_dqs_delay_5 to dll_dqs_delay_8 */
mtdcr(ddrcfga, DDR0_19);
val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
| DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
| DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
| DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
| DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
mtdcr(ddrcfgd, val);
/* clear any ECC errors */
mtdcr(ddrcfga, DDR0_00);
mtdcr(ddrcfgd,
mfdcr(ddrcfgd) | DDR0_00_INT_ACK_ENCODE(0x3C));
sync();
eieio();
/* -----------------------------------------------------------+
* Assert 'start' parameter.
* ----------------------------------------------------------*/
mtdcr(ddrcfga, DDR0_02);
val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
DDR0_02_START_ON;
mtdcr(ddrcfgd, val);
sync();
eieio();
/* -----------------------------------------------------------+
* Wait for the DCC master delay line to finish calibration
* ----------------------------------------------------------*/
if (denali_wait_for_dlllock() != 0) {
printf("dll lock did not occur !!!\n");
printf("denali_core_search_data_eye!!!\n");
printf("wr_dqs_shift = %d - dll_dqs_delay_X = "
"%d\n", wr_dqs_shift, dll_dqs_delay_X);
hang();
}
sync();
eieio();
if (wait_for_dram_init_complete() != 0) {
printf("dram init complete did not occur!!!\n");
printf("denali_core_search_data_eye!!!\n");
printf("wr_dqs_shift = %d - dll_dqs_delay_X = "
"%d\n", wr_dqs_shift, dll_dqs_delay_X);
hang();
}
udelay(100); /* wait 100us to ensure init is really completed !!! */
/* write values */
for (j = 0; j < NUM_TRIES; j++) {
ram_pointer[j] = test[j];
/* clear any cache at ram location */
__asm__("dcbf 0,%0": :"r"(&ram_pointer[j]));
}
/* read values back */
for (j = 0; j < NUM_TRIES; j++) {
for (k = 0; k < NUM_READS; k++) {
/* clear any cache at ram location */
__asm__("dcbf 0,%0": :"r"(&ram_pointer
[j]));
if (ram_pointer[j] != test[j])
break;
}
/* read error */
if (k != NUM_READS)
break;
}
/* See if the dll_dqs_delay_X value passed. */
mtdcr(ddrcfga, DDR0_00);
if (j < NUM_TRIES
|| (DDR0_00_INT_STATUS_DECODE(mfdcr(ddrcfgd)) &
0x3F)) {
/* Failed */
passing_cases = 0;
/* break; */
} else {
/* Passed */
if (passing_cases == 0)
dll_dqs_delay_X_sw_val =
dll_dqs_delay_X;
passing_cases++;
if (passing_cases >= max_passing_cases) {
max_passing_cases = passing_cases;
wr_dqs_shift_with_max_passing_cases =
wr_dqs_shift;
dll_dqs_delay_X_start_window =
dll_dqs_delay_X_sw_val;
dll_dqs_delay_X_end_window =
dll_dqs_delay_X;
}
}
/* -----------------------------------------------------------+
* De-assert 'start' parameter.
* ----------------------------------------------------------*/
mtdcr(ddrcfga, DDR0_02);
val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) |
DDR0_02_START_OFF;
mtdcr(ddrcfgd, val);
} /* for (dll_dqs_delay_X=0; dll_dqs_delay_X<128; dll_dqs_delay_X++) */
} /* for (wr_dqs_shift=0; wr_dqs_shift<96; wr_dqs_shift++) */
/* -----------------------------------------------------------+
* Largest passing window is now detected.
* ----------------------------------------------------------*/
/* Compute dll_dqs_delay_X value */
dll_dqs_delay_X = (dll_dqs_delay_X_end_window +
dll_dqs_delay_X_start_window) / 2;
wr_dqs_shift = wr_dqs_shift_with_max_passing_cases;
debug("DQS calibration - Window detected:\n");
debug("max_passing_cases = %d\n", max_passing_cases);
debug("wr_dqs_shift = %d\n", wr_dqs_shift);
debug("dll_dqs_delay_X = %d\n", dll_dqs_delay_X);
debug("dll_dqs_delay_X window = %d - %d\n",
dll_dqs_delay_X_start_window, dll_dqs_delay_X_end_window);
/* -----------------------------------------------------------+
* De-assert 'start' parameter.
* ----------------------------------------------------------*/
mtdcr(ddrcfga, DDR0_02);
val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_OFF;
mtdcr(ddrcfgd, val);
/* -----------------------------------------------------------+
* Set 'wr_dqs_shift'
* ----------------------------------------------------------*/
mtdcr(ddrcfga, DDR0_09);
val = (mfdcr(ddrcfgd) & ~DDR0_09_WR_DQS_SHIFT_MASK)
| DDR0_09_WR_DQS_SHIFT_ENCODE(wr_dqs_shift);
mtdcr(ddrcfgd, val);
debug("DDR0_09=0x%08x\n", val);
/* -----------------------------------------------------------+
* Set 'dqs_out_shift' = wr_dqs_shift + 32
* ----------------------------------------------------------*/
dqs_out_shift = wr_dqs_shift + 32;
mtdcr(ddrcfga, DDR0_22);
val = (mfdcr(ddrcfgd) & ~DDR0_22_DQS_OUT_SHIFT_MASK)
| DDR0_22_DQS_OUT_SHIFT_ENCODE(dqs_out_shift);
mtdcr(ddrcfgd, val);
debug("DDR0_22=0x%08x\n", val);
/* -----------------------------------------------------------+
* Set 'dll_dqs_delay_X'.
* ----------------------------------------------------------*/
/* dll_dqs_delay_0 */
mtdcr(ddrcfga, DDR0_17);
val = (mfdcr(ddrcfgd) & ~DDR0_17_DLL_DQS_DELAY_0_MASK)
| DDR0_17_DLL_DQS_DELAY_0_ENCODE(dll_dqs_delay_X);
mtdcr(ddrcfgd, val);
debug("DDR0_17=0x%08x\n", val);
/* dll_dqs_delay_1 to dll_dqs_delay_4 */
mtdcr(ddrcfga, DDR0_18);
val = (mfdcr(ddrcfgd) & ~DDR0_18_DLL_DQS_DELAY_X_MASK)
| DDR0_18_DLL_DQS_DELAY_4_ENCODE(dll_dqs_delay_X)
| DDR0_18_DLL_DQS_DELAY_3_ENCODE(dll_dqs_delay_X)
| DDR0_18_DLL_DQS_DELAY_2_ENCODE(dll_dqs_delay_X)
| DDR0_18_DLL_DQS_DELAY_1_ENCODE(dll_dqs_delay_X);
mtdcr(ddrcfgd, val);
debug("DDR0_18=0x%08x\n", val);
/* dll_dqs_delay_5 to dll_dqs_delay_8 */
mtdcr(ddrcfga, DDR0_19);
val = (mfdcr(ddrcfgd) & ~DDR0_19_DLL_DQS_DELAY_X_MASK)
| DDR0_19_DLL_DQS_DELAY_8_ENCODE(dll_dqs_delay_X)
| DDR0_19_DLL_DQS_DELAY_7_ENCODE(dll_dqs_delay_X)
| DDR0_19_DLL_DQS_DELAY_6_ENCODE(dll_dqs_delay_X)
| DDR0_19_DLL_DQS_DELAY_5_ENCODE(dll_dqs_delay_X);
mtdcr(ddrcfgd, val);
debug("DDR0_19=0x%08x\n", val);
/* -----------------------------------------------------------+
* Assert 'start' parameter.
* ----------------------------------------------------------*/
mtdcr(ddrcfga, DDR0_02);
val = (mfdcr(ddrcfgd) & ~DDR0_02_START_MASK) | DDR0_02_START_ON;
mtdcr(ddrcfgd, val);
sync();
eieio();
/* -----------------------------------------------------------+
* Wait for the DCC master delay line to finish calibration
* ----------------------------------------------------------*/
if (denali_wait_for_dlllock() != 0) {
printf("dll lock did not occur !!!\n");
hang();
}
sync();
eieio();
if (wait_for_dram_init_complete() != 0) {
printf("dram init complete did not occur !!!\n");
hang();
}
udelay(100); /* wait 100us to ensure init is really completed !!! */
}
#endif /* defined(CONFIG_DDR_DATA_EYE) */
#endif /* defined(CONFIG_440EPX) || defined(CONFIG_440GRX) */

File diff suppressed because it is too large Load Diff

View File

@ -1,188 +0,0 @@
/*
* Copyright (c) 2008 Nuovation System Designs, LLC
* Grant Erickson <gerickson@nuovations.com>
*
* (C) Copyright 2005-2009
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2002
* Jun Gu, Artesyn Technology, jung@artesyncp.com
*
* (C) Copyright 2001
* Bill Hunter, Wave 7 Optics, williamhunter@attbi.com
*
* SPDX-License-Identifier: GPL-2.0+
*
* Description:
* This file implements generic DRAM ECC initialization for
* PowerPC processors using a SDRAM DDR/DDR2 controller,
* including the 405EX(r), 440GP/GX/EP/GR, 440SP(E), and
* 460EX/GT.
*/
#include <common.h>
#include <asm/ppc4xx.h>
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/mmu.h>
#include <asm/cache.h>
#include "ecc.h"
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR) || \
defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
#if defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC)
#if defined(CONFIG_405EX)
/*
* Currently only 405EX uses 16bit data bus width as an alternative
* option to 32bit data width (SDRAM0_MCOPT1_WDTH)
*/
#define SDRAM_DATA_ALT_WIDTH 2
#else
#define SDRAM_DATA_ALT_WIDTH 8
#endif
static void wait_ddr_idle(void)
{
u32 val;
do {
mfsdram(SDRAM_MCSTAT, val);
} while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT);
}
static void program_ecc_addr(unsigned long start_address,
unsigned long num_bytes,
unsigned long tlb_word2_i_value)
{
unsigned long current_address;
unsigned long end_address;
unsigned long address_increment;
unsigned long mcopt1;
char str[] = "ECC generation -";
char slash[] = "\\|/-\\|/-";
int loop = 0;
int loopi = 0;
current_address = start_address;
mfsdram(SDRAM_MCOPT1, mcopt1);
if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) {
mtsdram(SDRAM_MCOPT1,
(mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_GEN);
sync();
eieio();
wait_ddr_idle();
puts(str);
#ifdef CONFIG_440
if (tlb_word2_i_value == TLB_WORD2_I_ENABLE) {
#endif
/* ECC bit set method for non-cached memory */
if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32)
address_increment = 4;
else
address_increment = SDRAM_DATA_ALT_WIDTH;
end_address = current_address + num_bytes;
while (current_address < end_address) {
*((unsigned long *)current_address) = 0;
current_address += address_increment;
if ((loop++ % (2 << 20)) == 0) {
putc('\b');
putc(slash[loopi++ % 8]);
}
}
#ifdef CONFIG_440
} else {
/* ECC bit set method for cached memory */
dcbz_area(start_address, num_bytes);
/* Write modified dcache lines back to memory */
clean_dcache_range(start_address, start_address + num_bytes);
}
#endif /* CONFIG_440 */
blank_string(strlen(str));
sync();
eieio();
wait_ddr_idle();
/* clear ECC error repoting registers */
mtsdram(SDRAM_ECCES, 0xffffffff);
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)
/*
* IBM DDR(1) core (440GX):
* Clear Mx bits in SDRAM0_BESR0/1
*/
mtsdram(SDRAM0_BESR0, 0xffffffff);
mtsdram(SDRAM0_BESR1, 0xffffffff);
#elif defined(CONFIG_440)
/*
* 440/460 DDR2 core:
* Clear EMID (Error PLB Master ID) in MQ0_ESL
*/
mtdcr(SDRAM_ERRSTATLL, 0xfff00000);
#else
/*
* 405EX(r) DDR2 core:
* Clear M0ID (Error PLB Master ID) in SDRAM_BESR
*/
mtsdram(SDRAM_BESR, 0xf0000000);
#endif
mtsdram(SDRAM_MCOPT1,
(mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_CHK_REP);
sync();
eieio();
wait_ddr_idle();
}
}
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)
void ecc_init(unsigned long * const start, unsigned long size)
{
/*
* Init ECC with cache disabled (on PPC's with IBM DDR
* controller (non DDR2), not tested with cache enabled yet
*/
program_ecc_addr((u32)start, size, TLB_WORD2_I_ENABLE);
}
#endif
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
void do_program_ecc(unsigned long tlb_word2_i_value)
{
unsigned long mcopt1;
unsigned long mcopt2;
unsigned long mcstat;
phys_size_t memsize = sdram_memsize();
if (memsize > CONFIG_MAX_MEM_MAPPED) {
printf("\nWarning: Can't enable ECC on systems with more than 2GB of SDRAM!\n");
return;
}
mfsdram(SDRAM_MCOPT1, mcopt1);
mfsdram(SDRAM_MCOPT2, mcopt2);
if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) {
/* DDR controller must be enabled and not in self-refresh. */
mfsdram(SDRAM_MCSTAT, mcstat);
if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE)
&& ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT)
&& ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK))
== (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) {
program_ecc_addr(0, memsize, tlb_word2_i_value);
}
}
}
#endif
#endif /* defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC) */
#endif /* defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)... */

View File

@ -1,58 +0,0 @@
/*
* Copyright (c) 2008 Nuovation System Designs, LLC
* Grant Erickson <gerickson@nuovations.com>
*
* Copyright (c) 2007-2009 DENX Software Engineering, GmbH
* Stefan Roese <sr@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*
* Description:
* This file implements ECC initialization for PowerPC processors
* using the IBM SDRAM DDR1 & DDR2 controller.
*/
#ifndef _ECC_H_
#define _ECC_H_
/*
* Since the IBM DDR controller used on 440GP/GX/EP/GR is not register
* compatible to the IBM DDR/2 controller used on 405EX/440SP/SPe/460EX/GT
* we need to make some processor dependant defines used later on by the
* driver.
*/
/* For 440GP/GX/EP/GR */
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)
#define SDRAM_MCOPT1 SDRAM_CFG0
#define SDRAM_MCOPT1_MCHK_MASK SDRAM_CFG0_MCHK_MASK
#define SDRAM_MCOPT1_MCHK_NON SDRAM_CFG0_MCHK_NON
#define SDRAM_MCOPT1_MCHK_GEN SDRAM_CFG0_MCHK_GEN
#define SDRAM_MCOPT1_MCHK_CHK SDRAM_CFG0_MCHK_CHK
#define SDRAM_MCOPT1_MCHK_CHK_REP SDRAM_CFG0_MCHK_CHK
#define SDRAM_MCOPT1_DMWD_MASK SDRAM_CFG0_DMWD_MASK
#define SDRAM_MCOPT1_DMWD_32 SDRAM_CFG0_DMWD_32
#define SDRAM_MCSTAT SDRAM0_MCSTS
#define SDRAM_MCSTAT_IDLE_MASK SDRAM_MCSTS_CIS
#define SDRAM_MCSTAT_IDLE_NOT SDRAM_MCSTS_IDLE_NOT
#define SDRAM_ECCES SDRAM0_ECCESR
#endif
void ecc_init(unsigned long * const start, unsigned long size);
void do_program_ecc(unsigned long tlb_word2_i_value);
static void inline blank_string(int size)
{
int i;
for (i = 0; i < size; i++)
putc('\b');
for (i = 0; i < size; i++)
putc(' ');
for (i = 0; i < size; i++)
putc('\b');
}
#endif /* _ECC_H_ */

View File

@ -1,157 +0,0 @@
/*
* (C) Copyright 2007-2008
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <asm/cache.h>
#include <asm/ppc4xx.h>
#ifdef CONFIG_OF_BOARD_SETUP
#include <libfdt.h>
#include <fdt_support.h>
#include <asm/4xx_pcie.h>
DECLARE_GLOBAL_DATA_PTR;
int __ft_board_setup(void *blob, bd_t *bd)
{
int rc;
int i;
u32 bxcr;
u32 ranges[EBC_NUM_BANKS * 4];
u32 *p = ranges;
char ebc_path[] = "/plb/opb/ebc";
ft_cpu_setup(blob, bd);
/*
* Read 4xx EBC bus bridge registers to get mappings of the
* peripheral banks into the OPB/PLB address space
*/
for (i = 0; i < EBC_NUM_BANKS; i++) {
mtdcr(EBC0_CFGADDR, EBC_BXCR(i));
bxcr = mfdcr(EBC0_CFGDATA);
if ((bxcr & EBC_BXCR_BU_MASK) != EBC_BXCR_BU_NONE) {
*p++ = i;
*p++ = 0;
*p++ = bxcr & EBC_BXCR_BAS_MASK;
*p++ = EBC_BXCR_BANK_SIZE(bxcr);
}
}
#ifdef CONFIG_FDT_FIXUP_NOR_FLASH_SIZE
/* Update reg property in all nor flash nodes too */
fdt_fixup_nor_flash_size(blob);
#endif
/* Some 405 PPC's have EBC as direct PLB child in the dts */
if (fdt_path_offset(blob, ebc_path) < 0)
strcpy(ebc_path, "/plb/ebc");
rc = fdt_find_and_setprop(blob, ebc_path, "ranges", ranges,
(p - ranges) * sizeof(u32), 1);
if (rc) {
printf("Unable to update property EBC mappings, err=%s\n",
fdt_strerror(rc));
}
return 0;
}
int ft_board_setup(void *blob, bd_t *bd)
__attribute__((weak, alias("__ft_board_setup")));
/*
* Fixup all PCIe nodes by setting the device_type property
* to "pci-endpoint" instead is "pci" for endpoint ports.
* This property will get checked later by the Linux driver
* to properly configure the PCIe port in Linux (again).
*/
void fdt_pcie_setup(void *blob)
{
const char *compat = "ibm,plb-pciex";
const char *prop = "device_type";
const char *prop_val = "pci-endpoint";
const u32 *port;
int no;
int rc;
/* Search first PCIe node */
no = fdt_node_offset_by_compatible(blob, -1, compat);
while (no != -FDT_ERR_NOTFOUND) {
port = fdt_getprop(blob, no, "port", NULL);
if (port == NULL) {
printf("WARNING: could not find port property\n");
} else {
if (is_end_point(*port)) {
rc = fdt_setprop(blob, no, prop, prop_val,
strlen(prop_val) + 1);
if (rc < 0)
printf("WARNING: could not set %s for %s: %s.\n",
prop, compat, fdt_strerror(rc));
}
}
/* Jump to next PCIe node */
no = fdt_node_offset_by_compatible(blob, no, compat);
}
}
void ft_cpu_setup(void *blob, bd_t *bd)
{
sys_info_t sys_info;
int off, ndepth = 0;
get_sys_info(&sys_info);
do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "timebase-frequency",
bd->bi_intfreq, 1);
do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "clock-frequency",
bd->bi_intfreq, 1);
do_fixup_by_path_u32(blob, "/plb", "clock-frequency", sys_info.freqPLB, 1);
do_fixup_by_path_u32(blob, "/plb/opb", "clock-frequency", sys_info.freqOPB, 1);
if (fdt_path_offset(blob, "/plb/opb/ebc") >= 0)
do_fixup_by_path_u32(blob, "/plb/opb/ebc", "clock-frequency",
sys_info.freqEBC, 1);
else
do_fixup_by_path_u32(blob, "/plb/ebc", "clock-frequency",
sys_info.freqEBC, 1);
fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
/*
* Fixup all UART clocks for CPU internal UARTs
* (only these UARTs are definitely clocked by gd->arch.uart_clk)
*
* These UARTs are direct childs of /plb/opb. This code
* does not touch any UARTs that are connected to the ebc.
*/
off = fdt_path_offset(blob, "/plb/opb");
while ((off = fdt_next_node(blob, off, &ndepth)) >= 0) {
/*
* process all sub nodes and stop when we are back
* at the starting depth
*/
if (ndepth <= 0)
break;
/* only update direct childs */
if ((ndepth == 1) &&
(fdt_node_check_compatible(blob, off, "ns16550") == 0))
fdt_setprop(blob, off,
"clock-frequency",
(void *)&gd->arch.uart_clk, 4);
}
/*
* Fixup all available PCIe nodes by setting the device_type property
*/
fdt_pcie_setup(blob);
}
#endif /* CONFIG_OF_BOARD_SETUP */

View File

@ -1,244 +0,0 @@
/*
* (C) Copyright 2007-2008
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/ppc4xx-gpio.h>
/* Only compile this file for boards with GPIO support */
#if defined(GPIO0_BASE)
#if defined(CONFIG_SYS_4xx_GPIO_TABLE)
gpio_param_s const gpio_tab[GPIO_GROUP_MAX][GPIO_MAX] = CONFIG_SYS_4xx_GPIO_TABLE;
#endif
#if defined(GPIO0_OSRL)
/* Only some 4xx variants support alternate funtions on the GPIO's */
void gpio_config(int pin, int in_out, int gpio_alt, int out_val)
{
u32 mask;
u32 mask2;
u32 val;
u32 offs = 0;
u32 offs2 = 0;
int pin2 = pin << 1;
if (pin >= GPIO_MAX) {
offs = 0x100;
pin -= GPIO_MAX;
}
if (pin >= GPIO_MAX/2) {
offs2 = 0x4;
pin2 = (pin - GPIO_MAX/2) << 1;
}
mask = 0x80000000 >> pin;
mask2 = 0xc0000000 >> pin2;
/* first set TCR to 0 */
out_be32((void *)GPIO0_TCR + offs, in_be32((void *)GPIO0_TCR + offs) & ~mask);
if (in_out == GPIO_OUT) {
val = in_be32((void *)GPIO0_OSRL + offs + offs2) & ~mask2;
switch (gpio_alt) {
case GPIO_ALT1:
val |= GPIO_ALT1_SEL >> pin2;
break;
case GPIO_ALT2:
val |= GPIO_ALT2_SEL >> pin2;
break;
case GPIO_ALT3:
val |= GPIO_ALT3_SEL >> pin2;
break;
}
out_be32((void *)GPIO0_OSRL + offs + offs2, val);
/* setup requested output value */
if (out_val == GPIO_OUT_0)
out_be32((void *)GPIO0_OR + offs,
in_be32((void *)GPIO0_OR + offs) & ~mask);
else if (out_val == GPIO_OUT_1)
out_be32((void *)GPIO0_OR + offs,
in_be32((void *)GPIO0_OR + offs) | mask);
/* now configure TCR to drive output if selected */
out_be32((void *)GPIO0_TCR + offs,
in_be32((void *)GPIO0_TCR + offs) | mask);
} else {
val = in_be32((void *)GPIO0_ISR1L + offs + offs2) & ~mask2;
val |= GPIO_IN_SEL >> pin2;
out_be32((void *)GPIO0_ISR1L + offs + offs2, val);
}
}
#endif /* GPIO_OSRL */
void gpio_write_bit(int pin, int val)
{
u32 offs = 0;
if (pin >= GPIO_MAX) {
offs = 0x100;
pin -= GPIO_MAX;
}
if (val)
out_be32((void *)GPIO0_OR + offs,
in_be32((void *)GPIO0_OR + offs) | GPIO_VAL(pin));
else
out_be32((void *)GPIO0_OR + offs,
in_be32((void *)GPIO0_OR + offs) & ~GPIO_VAL(pin));
}
int gpio_read_out_bit(int pin)
{
u32 offs = 0;
if (pin >= GPIO_MAX) {
offs = 0x100;
pin -= GPIO_MAX;
}
return (in_be32((void *)GPIO0_OR + offs) & GPIO_VAL(pin) ? 1 : 0);
}
int gpio_read_in_bit(int pin)
{
u32 offs = 0;
if (pin >= GPIO_MAX) {
offs = 0x100;
pin -= GPIO_MAX;
}
return (in_be32((void *)GPIO0_IR + offs) & GPIO_VAL(pin) ? 1 : 0);
}
#if defined(CONFIG_SYS_4xx_GPIO_TABLE)
void gpio_set_chip_configuration(void)
{
unsigned char i=0, j=0, offs=0, gpio_core;
unsigned long reg, core_add;
for (gpio_core=0; gpio_core<GPIO_GROUP_MAX; gpio_core++) {
j = 0;
offs = 0;
/* GPIO config of the GPIOs 0 to 31 */
for (i=0; i<GPIO_MAX; i++, j++) {
if (i == GPIO_MAX/2) {
offs = 4;
j = i-16;
}
core_add = gpio_tab[gpio_core][i].add;
if ((gpio_tab[gpio_core][i].in_out == GPIO_IN) ||
(gpio_tab[gpio_core][i].in_out == GPIO_BI)) {
switch (gpio_tab[gpio_core][i].alt_nb) {
case GPIO_SEL:
break;
case GPIO_ALT1:
reg = in_be32((void *)GPIO_IS1(core_add+offs))
& ~(GPIO_MASK >> (j*2));
reg = reg | (GPIO_IN_SEL >> (j*2));
out_be32((void *)GPIO_IS1(core_add+offs), reg);
break;
case GPIO_ALT2:
reg = in_be32((void *)GPIO_IS2(core_add+offs))
& ~(GPIO_MASK >> (j*2));
reg = reg | (GPIO_IN_SEL >> (j*2));
out_be32((void *)GPIO_IS2(core_add+offs), reg);
break;
case GPIO_ALT3:
reg = in_be32((void *)GPIO_IS3(core_add+offs))
& ~(GPIO_MASK >> (j*2));
reg = reg | (GPIO_IN_SEL >> (j*2));
out_be32((void *)GPIO_IS3(core_add+offs), reg);
break;
}
}
if ((gpio_tab[gpio_core][i].in_out == GPIO_OUT) ||
(gpio_tab[gpio_core][i].in_out == GPIO_BI)) {
u32 gpio_alt_sel = 0;
switch (gpio_tab[gpio_core][i].alt_nb) {
case GPIO_SEL:
/*
* Setup output value
* 1 -> high level
* 0 -> low level
* else -> don't touch
*/
reg = in_be32((void *)GPIO_OR(core_add));
if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)
reg |= (0x80000000 >> (i));
else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)
reg &= ~(0x80000000 >> (i));
out_be32((void *)GPIO_OR(core_add), reg);
reg = in_be32((void *)GPIO_TCR(core_add)) |
(0x80000000 >> (i));
out_be32((void *)GPIO_TCR(core_add), reg);
reg = in_be32((void *)GPIO_OS(core_add+offs))
& ~(GPIO_MASK >> (j*2));
out_be32((void *)GPIO_OS(core_add+offs), reg);
reg = in_be32((void *)GPIO_TS(core_add+offs))
& ~(GPIO_MASK >> (j*2));
out_be32((void *)GPIO_TS(core_add+offs), reg);
break;
case GPIO_ALT1:
gpio_alt_sel = GPIO_ALT1_SEL;
break;
case GPIO_ALT2:
gpio_alt_sel = GPIO_ALT2_SEL;
break;
case GPIO_ALT3:
gpio_alt_sel = GPIO_ALT3_SEL;
break;
}
if (0 != gpio_alt_sel) {
reg = in_be32((void *)GPIO_OS(core_add+offs))
& ~(GPIO_MASK >> (j*2));
reg = reg | (gpio_alt_sel >> (j*2));
out_be32((void *)GPIO_OS(core_add+offs), reg);
if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1) {
reg = in_be32((void *)GPIO_TCR(core_add))
| (0x80000000 >> (i));
out_be32((void *)GPIO_TCR(core_add), reg);
reg = in_be32((void *)GPIO_TS(core_add+offs))
& ~(GPIO_MASK >> (j*2));
out_be32((void *)GPIO_TS(core_add+offs), reg);
} else {
reg = in_be32((void *)GPIO_TCR(core_add))
& ~(0x80000000 >> (i));
out_be32((void *)GPIO_TCR(core_add), reg);
reg = in_be32((void *)GPIO_TS(core_add+offs))
& ~(GPIO_MASK >> (j*2));
reg = reg | (gpio_alt_sel >> (j*2));
out_be32((void *)GPIO_TS(core_add+offs), reg);
}
}
}
}
}
}
#endif /* GPIO0_BASE */
#endif /* CONFIG_SYS_4xx_GPIO_TABLE */

View File

@ -1,192 +0,0 @@
/*
* (C) Copyright 2000-2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2002 (440 port)
* Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com
*
* (C) Copyright 2003 (440GX port)
* Travis B. Sawyer, Sandburst Corporation, tsawyer@sandburst.com
*
* (C) Copyright 2008 (PPC440X05 port for Virtex 5 FX)
* Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@gmail.com
* Work supported by Qtechnology (htpp://qtec.com)
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <asm/processor.h>
#include <asm/interrupt.h>
#include <asm/ppc4xx.h>
#include <ppc_asm.tmpl>
DECLARE_GLOBAL_DATA_PTR;
/*
* CPM interrupt vector functions.
*/
struct irq_action {
interrupt_handler_t *handler;
void *arg;
int count;
};
static struct irq_action irq_vecs[IRQ_MAX];
#if defined(CONFIG_440)
/* SPRN changed in 440 */
static __inline__ void set_evpr(unsigned long val)
{
asm volatile("mtspr 0x03f,%0" : : "r" (val));
}
#else /* !defined(CONFIG_440) */
static __inline__ void set_pit(unsigned long val)
{
asm volatile("mtpit %0" : : "r" (val));
}
static __inline__ void set_evpr(unsigned long val)
{
asm volatile("mtevpr %0" : : "r" (val));
}
#endif /* defined(CONFIG_440 */
int interrupt_init_cpu (unsigned *decrementer_count)
{
int vec;
unsigned long val;
/* decrementer is automatically reloaded */
*decrementer_count = 0;
/*
* Mark all irqs as free
*/
for (vec = 0; vec < IRQ_MAX; vec++) {
irq_vecs[vec].handler = NULL;
irq_vecs[vec].arg = NULL;
irq_vecs[vec].count = 0;
}
#ifdef CONFIG_4xx
/*
* Init PIT
*/
#if defined(CONFIG_440)
val = mfspr( SPRN_TCR );
val &= (~0x04400000); /* clear DIS & ARE */
mtspr( SPRN_TCR, val );
mtspr( SPRN_DEC, 0 ); /* Prevent exception after TSR clear*/
mtspr( SPRN_DECAR, 0 ); /* clear reload */
mtspr( SPRN_TSR, 0x08000000 ); /* clear DEC status */
val = gd->bd->bi_intfreq/1000; /* 1 msec */
mtspr( SPRN_DECAR, val ); /* Set auto-reload value */
mtspr( SPRN_DEC, val ); /* Set inital val */
#else
set_pit(gd->bd->bi_intfreq / 1000);
#endif
#endif /* CONFIG_4xx */
#ifdef CONFIG_ADCIOP
/*
* Init PIT
*/
set_pit(66000);
#endif
/*
* Enable PIT
*/
val = mfspr(SPRN_TCR);
val |= 0x04400000;
mtspr(SPRN_TCR, val);
/*
* Set EVPR to 0
*/
set_evpr(0x00000000);
/*
* Call uic or xilinx_irq pic_enable
*/
pic_enable();
return (0);
}
void timer_interrupt_cpu(struct pt_regs *regs)
{
/* nothing to do here */
return;
}
void interrupt_run_handler(int vec)
{
irq_vecs[vec].count++;
if (irq_vecs[vec].handler != NULL) {
/* call isr */
(*irq_vecs[vec].handler) (irq_vecs[vec].arg);
} else {
pic_irq_disable(vec);
printf("Masking bogus interrupt vector %d\n", vec);
}
pic_irq_ack(vec);
return;
}
void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg)
{
/*
* Print warning when replacing with a different irq vector
*/
if ((irq_vecs[vec].handler != NULL) && (irq_vecs[vec].handler != handler)) {
printf("Interrupt vector %d: handler 0x%x replacing 0x%x\n",
vec, (uint) handler, (uint) irq_vecs[vec].handler);
}
irq_vecs[vec].handler = handler;
irq_vecs[vec].arg = arg;
pic_irq_enable(vec);
return;
}
void irq_free_handler(int vec)
{
debug("Free interrupt for vector %d ==> %p\n",
vec, irq_vecs[vec].handler);
pic_irq_disable(vec);
irq_vecs[vec].handler = NULL;
irq_vecs[vec].arg = NULL;
return;
}
#if defined(CONFIG_CMD_IRQ)
int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int vec;
printf ("Interrupt-Information:\n");
printf ("Nr Routine Arg Count\n");
for (vec = 0; vec < IRQ_MAX; vec++) {
if (irq_vecs[vec].handler != NULL) {
printf ("%02d %08lx %08lx %d\n",
vec,
(ulong)irq_vecs[vec].handler,
(ulong)irq_vecs[vec].arg,
irq_vecs[vec].count);
}
}
return 0;
}
#endif

View File

@ -1,60 +0,0 @@
/*
* Copyright (C) 2000 Murray Jensen <Murray.Jensen@cmst.csiro.au>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
#include <command.h>
#include <asm/ppc4xx.h>
#define CONFIG_405GP 1 /* needed for Linux kernel header files */
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
#if defined(CONFIG_CMD_KGDB)
/*
* cache flushing routines for kgdb
*/
.globl kgdb_flush_cache_all
kgdb_flush_cache_all:
/* icache */
iccci r0,r0 /* iccci invalidates the entire I cache */
/* dcache */
addi r6,0,0x0000 /* clear GPR 6 */
addi r7,r0, 128 /* do loop for # of dcache lines */
/* NOTE: dccci invalidates both */
mtctr r7 /* ways in the D cache */
..dcloop:
dccci 0,r6 /* invalidate line */
addi r6,r6, 32 /* bump to next line */
bdnz ..dcloop
blr
.globl kgdb_flush_cache_range
kgdb_flush_cache_range:
li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
mr r6,r3
1: dcbst 0,r3
addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbst's to get to ram */
mtctr r4
2: icbi 0,r6
addi r6,r6,L1_CACHE_BYTES
bdnz 2b
SYNC
blr
#endif

View File

@ -1,343 +0,0 @@
/*
* SPDX-License-Identifier: GPL-2.0 IBM-pibs
*/
/*-----------------------------------------------------------------------------+
|
| File Name: miiphy.c
|
| Function: This module has utilities for accessing the MII PHY through
| the EMAC3 macro.
|
| Author: Mark Wisner
|
+-----------------------------------------------------------------------------*/
/* define DEBUG for debugging output (obviously ;-)) */
#if 0
#define DEBUG
#endif
#include <common.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <ppc_asm.tmpl>
#include <asm/ppc4xx.h>
#include <asm/ppc4xx-emac.h>
#include <asm/ppc4xx-mal.h>
#include <miiphy.h>
#if !defined(CONFIG_PHY_CLK_FREQ)
#define CONFIG_PHY_CLK_FREQ 0
#endif
/***********************************************************/
/* Dump out to the screen PHY regs */
/***********************************************************/
void miiphy_dump (char *devname, unsigned char addr)
{
unsigned long i;
unsigned short data;
for (i = 0; i < 0x1A; i++) {
if (miiphy_read (devname, addr, i, &data)) {
printf ("read error for reg %lx\n", i);
return;
}
printf ("Phy reg %lx ==> %4x\n", i, data);
/* jump to the next set of regs */
if (i == 0x07)
i = 0x0f;
} /* end for loop */
} /* end dump */
/***********************************************************/
/* (Re)start autonegotiation */
/***********************************************************/
int phy_setup_aneg (char *devname, unsigned char addr)
{
u16 bmcr;
#if defined(CONFIG_PHY_DYNAMIC_ANEG)
/*
* Set up advertisement based on capablilities reported by the PHY.
* This should work for both copper and fiber.
*/
u16 bmsr;
#if defined(CONFIG_PHY_GIGE)
u16 exsr = 0x0000;
#endif
miiphy_read (devname, addr, MII_BMSR, &bmsr);
#if defined(CONFIG_PHY_GIGE)
if (bmsr & BMSR_ESTATEN)
miiphy_read (devname, addr, MII_ESTATUS, &exsr);
if (exsr & (ESTATUS_1000XF | ESTATUS_1000XH)) {
/* 1000BASE-X */
u16 anar = 0x0000;
if (exsr & ESTATUS_1000XF)
anar |= ADVERTISE_1000XFULL;
if (exsr & ESTATUS_1000XH)
anar |= ADVERTISE_1000XHALF;
miiphy_write (devname, addr, MII_ADVERTISE, anar);
} else
#endif
{
u16 anar, btcr;
miiphy_read (devname, addr, MII_ADVERTISE, &anar);
anar &= ~(0x5000 | LPA_100BASE4 | LPA_100FULL |
LPA_100HALF | LPA_10FULL | LPA_10HALF);
miiphy_read (devname, addr, MII_CTRL1000, &btcr);
btcr &= ~(0x00FF | PHY_1000BTCR_1000FD | PHY_1000BTCR_1000HD);
if (bmsr & BMSR_100BASE4)
anar |= LPA_100BASE4;
if (bmsr & BMSR_100FULL)
anar |= LPA_100FULL;
if (bmsr & BMSR_100HALF)
anar |= LPA_100HALF;
if (bmsr & BMSR_10FULL)
anar |= LPA_10FULL;
if (bmsr & BMSR_10HALF)
anar |= LPA_10HALF;
miiphy_write (devname, addr, MII_ADVERTISE, anar);
#if defined(CONFIG_PHY_GIGE)
if (exsr & ESTATUS_1000_TFULL)
btcr |= PHY_1000BTCR_1000FD;
if (exsr & ESTATUS_1000_THALF)
btcr |= PHY_1000BTCR_1000HD;
miiphy_write (devname, addr, MII_CTRL1000, btcr);
#endif
}
#else /* defined(CONFIG_PHY_DYNAMIC_ANEG) */
/*
* Set up standard advertisement
*/
u16 adv;
miiphy_read (devname, addr, MII_ADVERTISE, &adv);
adv |= (LPA_LPACK | LPA_100FULL | LPA_100HALF |
LPA_10FULL | LPA_10HALF);
miiphy_write (devname, addr, MII_ADVERTISE, adv);
miiphy_read (devname, addr, MII_CTRL1000, &adv);
adv |= (0x0300);
miiphy_write (devname, addr, MII_CTRL1000, adv);
#endif /* defined(CONFIG_PHY_DYNAMIC_ANEG) */
/* Start/Restart aneg */
miiphy_read (devname, addr, MII_BMCR, &bmcr);
bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
miiphy_write (devname, addr, MII_BMCR, bmcr);
return 0;
}
/***********************************************************/
/* read a phy reg and return the value with a rc */
/***********************************************************/
/* AMCC_TODO:
* Find out of the choice for the emac for MDIO is from the bridges,
* i.e. ZMII or RGMII as approporiate. If the bridges are not used
* to determine the emac for MDIO, then is the SDR0_ETH_CFG[MDIO_SEL]
* used? If so, then this routine below does not apply to the 460EX/GT.
*
* sr: Currently on 460EX only EMAC0 works with MDIO, so we always
* return EMAC0 offset here
* vg: For 460EX/460GT if internal GPCS PHY address is specified
* return appropriate EMAC offset
*/
unsigned int miiphy_getemac_offset(u8 addr)
{
#if defined(CONFIG_440) && \
!defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
!defined(CONFIG_460EX) && !defined(CONFIG_460GT)
unsigned long zmii;
unsigned long eoffset;
/* Need to find out which mdi port we're using */
zmii = in_be32((void *)ZMII0_FER);
if (zmii & (ZMII_FER_MDI << ZMII_FER_V (0)))
/* using port 0 */
eoffset = 0;
else if (zmii & (ZMII_FER_MDI << ZMII_FER_V (1)))
/* using port 1 */
eoffset = 0x100;
else if (zmii & (ZMII_FER_MDI << ZMII_FER_V (2)))
/* using port 2 */
eoffset = 0x400;
else if (zmii & (ZMII_FER_MDI << ZMII_FER_V (3)))
/* using port 3 */
eoffset = 0x600;
else {
/* None of the mdi ports are enabled! */
/* enable port 0 */
zmii |= ZMII_FER_MDI << ZMII_FER_V (0);
out_be32((void *)ZMII0_FER, zmii);
eoffset = 0;
/* need to soft reset port 0 */
zmii = in_be32((void *)EMAC0_MR0);
zmii |= EMAC_MR0_SRST;
out_be32((void *)EMAC0_MR0, zmii);
}
return (eoffset);
#else
#if defined(CONFIG_405EX)
unsigned long rgmii;
int devnum = 1;
rgmii = in_be32((void *)RGMII_FER);
if (rgmii & (1 << (19 - devnum)))
return 0x100;
#endif
#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
u32 eoffset = 0;
switch (addr) {
#if defined(CONFIG_HAS_ETH1) && defined(CONFIG_GPCS_PHY1_ADDR)
case CONFIG_GPCS_PHY1_ADDR:
if (addr == EMAC_MR1_IPPA_GET(in_be32((void *)EMAC0_MR1 + 0x100)))
eoffset = 0x100;
break;
#endif
#if defined(CONFIG_HAS_ETH2) && defined(CONFIG_GPCS_PHY2_ADDR)
case CONFIG_GPCS_PHY2_ADDR:
if (addr == EMAC_MR1_IPPA_GET(in_be32((void *)EMAC0_MR1 + 0x300)))
eoffset = 0x300;
break;
#endif
#if defined(CONFIG_HAS_ETH3) && defined(CONFIG_GPCS_PHY3_ADDR)
case CONFIG_GPCS_PHY3_ADDR:
if (addr == EMAC_MR1_IPPA_GET(in_be32((void *)EMAC0_MR1 + 0x400)))
eoffset = 0x400;
break;
#endif
default:
eoffset = 0;
break;
}
return eoffset;
#endif
return 0;
#endif
}
static int emac_miiphy_wait(u32 emac_reg)
{
u32 sta_reg;
int i;
/* wait for completion */
i = 0;
do {
sta_reg = in_be32((void *)EMAC0_STACR + emac_reg);
if (i++ > 5) {
debug("%s [%d]: Timeout! EMAC0_STACR=0x%0x\n", __func__,
__LINE__, sta_reg);
return -1;
}
udelay(10);
} while ((sta_reg & EMAC_STACR_OC) == EMAC_STACR_OC_MASK);
return 0;
}
static int emac_miiphy_command(u8 addr, u8 reg, int cmd, u16 value)
{
u32 emac_reg;
u32 sta_reg;
emac_reg = miiphy_getemac_offset(addr);
/* wait for completion */
if (emac_miiphy_wait(emac_reg) != 0)
return -1;
sta_reg = reg; /* reg address */
/* set clock (50MHz) and read flags */
#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
defined(CONFIG_405EX)
#if defined(CONFIG_IBM_EMAC4_V4) /* EMAC4 V4 changed bit setting */
sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | cmd;
#else
sta_reg |= cmd;
#endif
#else
sta_reg = (sta_reg | cmd) & ~EMAC_STACR_CLK_100MHZ;
#endif
/* Some boards (mainly 405EP based) define the PHY clock freqency fixed */
sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ;
sta_reg = sta_reg | ((u32)addr << 5); /* Phy address */
sta_reg = sta_reg | EMAC_STACR_OC_MASK; /* new IBM emac v4 */
if (cmd == EMAC_STACR_WRITE)
memcpy(&sta_reg, &value, 2); /* put in data */
out_be32((void *)EMAC0_STACR + emac_reg, sta_reg);
debug("%s [%d]: sta_reg=%08x\n", __func__, __LINE__, sta_reg);
/* wait for completion */
if (emac_miiphy_wait(emac_reg) != 0)
return -1;
debug("%s [%d]: sta_reg=%08x\n", __func__, __LINE__, sta_reg);
if ((sta_reg & EMAC_STACR_PHYE) != 0)
return -1;
return 0;
}
int emac4xx_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
{
unsigned long sta_reg;
unsigned long emac_reg;
emac_reg = miiphy_getemac_offset(addr);
if (emac_miiphy_command(addr, reg, EMAC_STACR_READ, 0) != 0)
return -1;
sta_reg = in_be32((void *)EMAC0_STACR + emac_reg);
return sta_reg >> 16;
}
/***********************************************************/
/* write a phy reg and return the value with a rc */
/***********************************************************/
int emac4xx_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
u16 value)
{
return emac_miiphy_command(addr, reg, EMAC_STACR_WRITE, value);
}

View File

@ -1,358 +0,0 @@
/*
*(C) Copyright 2005-2009 Netstal Maschinen AG
* Bruno Hars (Bruno.Hars@netstal.com)
* Niklaus Giger (Niklaus.Giger@netstal.com)
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*
* reginfo.c - register dump of HW-configuratin register for PPC4xx based board
*/
#include <common.h>
#include <command.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/ppc4xx.h>
#include <asm/ppc4xx-uic.h>
#include <asm/ppc4xx-emac.h>
enum REGISTER_TYPE {
IDCR1, /* Indirectly Accessed DCR via SDRAM0_CFGADDR/SDRAM0_CFGDATA */
IDCR2, /* Indirectly Accessed DCR via EBC0_CFGADDR/EBC0_CFGDATA */
IDCR3, /* Indirectly Accessed DCR via EBM0_CFGADDR/EBM0_CFGDATA */
IDCR4, /* Indirectly Accessed DCR via PPM0_CFGADDR/PPM0_CFGDATA */
IDCR5, /* Indirectly Accessed DCR via CPR0_CFGADDR/CPR0_CFGDATA */
IDCR6, /* Indirectly Accessed DCR via SDR0_CFGADDR/SDR0_CFGDATA */
MM /* Directly Accessed MMIO Register */
};
struct cpu_register {
char *name;
enum REGISTER_TYPE type;
u32 address;
};
/*
* PPC440EPx registers ordered for output
* name type addr size
* -------------------------------------------
*/
const struct cpu_register ppc4xx_reg[] = {
{"PB0CR", IDCR2, PB0CR},
{"PB0AP", IDCR2, PB0AP},
{"PB1CR", IDCR2, PB1CR},
{"PB1AP", IDCR2, PB1AP},
{"PB2CR", IDCR2, PB2CR},
{"PB2AP", IDCR2, PB2AP},
{"PB3CR", IDCR2, PB3CR},
{"PB3AP", IDCR2, PB3AP},
{"PB4CR", IDCR2, PB4CR},
{"PB4AP", IDCR2, PB4AP},
#if !defined(CONFIG_405EP)
{"PB5CR", IDCR2, PB5CR},
{"PB5AP", IDCR2, PB5AP},
{"PB6CR", IDCR2, PB6CR},
{"PB6AP", IDCR2, PB6AP},
{"PB7CR", IDCR2, PB7CR},
{"PB7AP", IDCR2, PB7AP},
#endif
{"PBEAR", IDCR2, PBEAR},
#if defined(CONFIG_405EP) || defined (CONFIG_405GP)
{"PBESR0", IDCR2, PBESR0},
{"PBESR1", IDCR2, PBESR1},
#endif
{"EBC0_CFG", IDCR2, EBC0_CFG},
#ifdef CONFIG_405GP
{"SDRAM0_BESR0", IDCR1, SDRAM0_BESR0},
{"SDRAM0_BESRS0", IDCR1, SDRAM0_BESRS0},
{"SDRAM0_BESR1", IDCR1, SDRAM0_BESR1},
{"SDRAM0_BESRS1", IDCR1, SDRAM0_BESRS1},
{"SDRAM0_BEAR", IDCR1, SDRAM0_BEAR},
{"SDRAM0_CFG", IDCR1, SDRAM0_CFG},
{"SDRAM0_RTR", IDCR1, SDRAM0_RTR},
{"SDRAM0_PMIT", IDCR1, SDRAM0_PMIT},
{"SDRAM0_B0CR", IDCR1, SDRAM0_B0CR},
{"SDRAM0_B1CR", IDCR1, SDRAM0_B1CR},
{"SDRAM0_B2CR", IDCR1, SDRAM0_B2CR},
{"SDRAM0_B3CR", IDCR1, SDRAM0_B1CR},
{"SDRAM0_TR", IDCR1, SDRAM0_TR},
{"SDRAM0_ECCCFG", IDCR1, SDRAM0_B1CR},
{"SDRAM0_ECCESR", IDCR1, SDRAM0_ECCESR},
#endif
#ifdef CONFIG_440EPX
{"SDR0_SDSTP0", IDCR6, SDR0_SDSTP0},
{"SDR0_SDSTP1", IDCR6, SDR0_SDSTP1},
{"SDR0_SDSTP2", IDCR6, SDR0_SDSTP2},
{"SDR0_SDSTP3", IDCR6, SDR0_SDSTP3},
{"SDR0_CUST0", IDCR6, SDR0_CUST0},
{"SDR0_CUST1", IDCR6, SDR0_CUST1},
{"SDR0_EBC", IDCR6, SDR0_EBC},
{"SDR0_AMP0", IDCR6, SDR0_AMP0},
{"SDR0_AMP1", IDCR6, SDR0_AMP1},
{"SDR0_CP440", IDCR6, SDR0_CP440},
{"SDR0_CRYP0", IDCR6, SDR0_CRYP0},
{"SDR0_DDRCFG", IDCR6, SDR0_DDRCFG},
{"SDR0_EMAC0RXST", IDCR6, SDR0_EMAC0RXST},
{"SDR0_EMAC0TXST", IDCR6, SDR0_EMAC0TXST},
{"SDR0_MFR", IDCR6, SDR0_MFR},
{"SDR0_PCI0", IDCR6, SDR0_PCI0},
{"SDR0_PFC0", IDCR6, SDR0_PFC0},
{"SDR0_PFC1", IDCR6, SDR0_PFC1},
{"SDR0_PFC2", IDCR6, SDR0_PFC2},
{"SDR0_PFC4", IDCR6, SDR0_PFC4},
{"SDR0_UART0", IDCR6, SDR0_UART0},
{"SDR0_UART1", IDCR6, SDR0_UART1},
{"SDR0_UART2", IDCR6, SDR0_UART2},
{"SDR0_UART3", IDCR6, SDR0_UART3},
{"DDR0_02", IDCR1, DDR0_02},
{"DDR0_00", IDCR1, DDR0_00},
{"DDR0_01", IDCR1, DDR0_01},
{"DDR0_03", IDCR1, DDR0_03},
{"DDR0_04", IDCR1, DDR0_04},
{"DDR0_05", IDCR1, DDR0_05},
{"DDR0_06", IDCR1, DDR0_06},
{"DDR0_07", IDCR1, DDR0_07},
{"DDR0_08", IDCR1, DDR0_08},
{"DDR0_09", IDCR1, DDR0_09},
{"DDR0_10", IDCR1, DDR0_10},
{"DDR0_11", IDCR1, DDR0_11},
{"DDR0_12", IDCR1, DDR0_12},
{"DDR0_14", IDCR1, DDR0_14},
{"DDR0_17", IDCR1, DDR0_17},
{"DDR0_18", IDCR1, DDR0_18},
{"DDR0_19", IDCR1, DDR0_19},
{"DDR0_20", IDCR1, DDR0_20},
{"DDR0_21", IDCR1, DDR0_21},
{"DDR0_22", IDCR1, DDR0_22},
{"DDR0_23", IDCR1, DDR0_23},
{"DDR0_24", IDCR1, DDR0_24},
{"DDR0_25", IDCR1, DDR0_25},
{"DDR0_26", IDCR1, DDR0_26},
{"DDR0_27", IDCR1, DDR0_27},
{"DDR0_28", IDCR1, DDR0_28},
{"DDR0_31", IDCR1, DDR0_31},
{"DDR0_32", IDCR1, DDR0_32},
{"DDR0_33", IDCR1, DDR0_33},
{"DDR0_34", IDCR1, DDR0_34},
{"DDR0_35", IDCR1, DDR0_35},
{"DDR0_36", IDCR1, DDR0_36},
{"DDR0_37", IDCR1, DDR0_37},
{"DDR0_38", IDCR1, DDR0_38},
{"DDR0_39", IDCR1, DDR0_39},
{"DDR0_40", IDCR1, DDR0_40},
{"DDR0_41", IDCR1, DDR0_41},
{"DDR0_42", IDCR1, DDR0_42},
{"DDR0_43", IDCR1, DDR0_43},
{"DDR0_44", IDCR1, DDR0_44},
{"CPR0_ICFG", IDCR5, CPR0_ICFG},
{"CPR0_MALD", IDCR5, CPR0_MALD},
{"CPR0_OPBD00", IDCR5, CPR0_OPBD0},
{"CPR0_PERD0", IDCR5, CPR0_PERD},
{"CPR0_PLLC0", IDCR5, CPR0_PLLC},
{"CPR0_PLLD0", IDCR5, CPR0_PLLD},
{"CPR0_PRIMAD0", IDCR5, CPR0_PRIMAD0},
{"CPR0_PRIMBD0", IDCR5, CPR0_PRIMBD0},
{"CPR0_SPCID", IDCR5, CPR0_SPCID},
{"SPI0_MODE", MM, SPI0_MODE},
{"IIC0_CLKDIV", MM, PCIL0_PMM1MA},
{"PCIL0_PMM0MA", MM, PCIL0_PMM0MA},
{"PCIL0_PMM1MA", MM, PCIL0_PMM1MA},
{"PCIL0_PTM1LA", MM, PCIL0_PMM1MA},
{"PCIL0_PTM1MS", MM, PCIL0_PTM1MS},
{"PCIL0_PTM2LA", MM, PCIL0_PMM1MA},
{"PCIL0_PTM2MS", MM, PCIL0_PTM2MS},
{"ZMII0_FER", MM, ZMII0_FER},
{"ZMII0_SSR", MM, ZMII0_SSR},
{"EMAC0_IPGVR", MM, EMAC0_IPGVR},
{"EMAC0_MR1", MM, EMAC0_MR1},
{"EMAC0_PTR", MM, EMAC0_PTR},
{"EMAC0_RWMR", MM, EMAC0_RWMR},
{"EMAC0_STACR", MM, EMAC0_STACR},
{"EMAC0_TMR0", MM, EMAC0_TMR0},
{"EMAC0_TMR1", MM, EMAC0_TMR1},
{"EMAC0_TRTR", MM, EMAC0_TRTR},
{"EMAC1_MR1", MM, EMAC1_MR1},
{"GPIO0_OR", MM, GPIO0_OR},
{"GPIO1_OR", MM, GPIO1_OR},
{"GPIO0_TCR", MM, GPIO0_TCR},
{"GPIO1_TCR", MM, GPIO1_TCR},
{"GPIO0_ODR", MM, GPIO0_ODR},
{"GPIO1_ODR", MM, GPIO1_ODR},
{"GPIO0_OSRL", MM, GPIO0_OSRL},
{"GPIO0_OSRH", MM, GPIO0_OSRH},
{"GPIO1_OSRL", MM, GPIO1_OSRL},
{"GPIO1_OSRH", MM, GPIO1_OSRH},
{"GPIO0_TSRL", MM, GPIO0_TSRL},
{"GPIO0_TSRH", MM, GPIO0_TSRH},
{"GPIO1_TSRL", MM, GPIO1_TSRL},
{"GPIO1_TSRH", MM, GPIO1_TSRH},
{"GPIO0_IR", MM, GPIO0_IR},
{"GPIO1_IR", MM, GPIO1_IR},
{"GPIO0_ISR1L", MM, GPIO0_ISR1L},
{"GPIO0_ISR1H", MM, GPIO0_ISR1H},
{"GPIO1_ISR1L", MM, GPIO1_ISR1L},
{"GPIO1_ISR1H", MM, GPIO1_ISR1H},
{"GPIO0_ISR2L", MM, GPIO0_ISR2L},
{"GPIO0_ISR2H", MM, GPIO0_ISR2H},
{"GPIO1_ISR2L", MM, GPIO1_ISR2L},
{"GPIO1_ISR2H", MM, GPIO1_ISR2H},
{"GPIO0_ISR3L", MM, GPIO0_ISR3L},
{"GPIO0_ISR3H", MM, GPIO0_ISR3H},
{"GPIO1_ISR3L", MM, GPIO1_ISR3L},
{"GPIO1_ISR3H", MM, GPIO1_ISR3H},
{"SDR0_USB2PHY0CR", IDCR6, SDR0_USB2PHY0CR},
{"SDR0_USB2H0CR", IDCR6, SDR0_USB2H0CR},
{"SDR0_USB2D0CR", IDCR6, SDR0_USB2D0CR},
#endif
};
/*
* CPU Register dump of PPC4xx HW configuration registers
* Output: first all DCR-registers, then in order of struct ppc4xx_reg
*/
#define PRINT_DCR(dcr) printf("0x%08x %-16s: 0x%08x\n", dcr,#dcr, mfdcr(dcr));
void ppc4xx_reginfo(void)
{
unsigned int i;
unsigned int n;
u32 value;
enum REGISTER_TYPE type;
#if defined (CONFIG_405EP)
printf("Dump PPC405EP HW configuration registers\n\n");
#elif CONFIG_405GP
printf ("Dump 405GP HW configuration registers\n\n");
#elif CONFIG_440EPX
printf("Dump PPC440EPx HW configuration registers\n\n");
#endif
printf("MSR: 0x%08x\n", mfmsr());
printf ("\nUniversal Interrupt Controller Regs\n");
PRINT_DCR(UIC0SR);
PRINT_DCR(UIC0ER);
PRINT_DCR(UIC0CR);
PRINT_DCR(UIC0PR);
PRINT_DCR(UIC0TR);
PRINT_DCR(UIC0MSR);
PRINT_DCR(UIC0VR);
PRINT_DCR(UIC0VCR);
#if (UIC_MAX > 1)
PRINT_DCR(UIC2SR);
PRINT_DCR(UIC2ER);
PRINT_DCR(UIC2CR);
PRINT_DCR(UIC2PR);
PRINT_DCR(UIC2TR);
PRINT_DCR(UIC2MSR);
PRINT_DCR(UIC2VR);
PRINT_DCR(UIC2VCR);
#endif
#if (UIC_MAX > 2)
PRINT_DCR(UIC2SR);
PRINT_DCR(UIC2ER);
PRINT_DCR(UIC2CR);
PRINT_DCR(UIC2PR);
PRINT_DCR(UIC2TR);
PRINT_DCR(UIC2MSR);
PRINT_DCR(UIC2VR);
PRINT_DCR(UIC2VCR);
#endif
#if (UIC_MAX > 3)
PRINT_DCR(UIC3SR);
PRINT_DCR(UIC3ER);
PRINT_DCR(UIC3CR);
PRINT_DCR(UIC3PR);
PRINT_DCR(UIC3TR);
PRINT_DCR(UIC3MSR);
PRINT_DCR(UIC3VR);
PRINT_DCR(UIC3VCR);
#endif
#if defined (CONFIG_405EP) || defined (CONFIG_405GP)
printf ("\n\nDMA Channels\n");
PRINT_DCR(DMASR);
PRINT_DCR(DMASGC);
PRINT_DCR(DMAADR);
PRINT_DCR(DMACR0);
PRINT_DCR(DMACT0);
PRINT_DCR(DMADA0);
PRINT_DCR(DMASA0);
PRINT_DCR(DMASB0);
PRINT_DCR(DMACR1);
PRINT_DCR(DMACT1);
PRINT_DCR(DMADA1);
PRINT_DCR(DMASA1);
PRINT_DCR(DMASB1);
PRINT_DCR(DMACR2);
PRINT_DCR(DMACT2);
PRINT_DCR(DMADA2);
PRINT_DCR(DMASA2);
PRINT_DCR(DMASB2);
PRINT_DCR(DMACR3);
PRINT_DCR(DMACT3);
PRINT_DCR(DMADA3);
PRINT_DCR(DMASA3);
PRINT_DCR(DMASB3);
#endif
printf ("\n\nVarious HW-Configuration registers\n");
#if defined (CONFIG_440EPX)
PRINT_DCR(MAL0_CFG);
PRINT_DCR(CPM0_ER);
PRINT_DCR(CPM1_ER);
PRINT_DCR(PLB4A0_ACR);
PRINT_DCR(PLB4A1_ACR);
PRINT_DCR(PLB3A0_ACR);
PRINT_DCR(OPB2PLB40_BCTRL);
PRINT_DCR(P4P3BO0_CFG);
#endif
n = ARRAY_SIZE(ppc4xx_reg);
for (i = 0; i < n; i++) {
value = 0;
type = ppc4xx_reg[i].type;
switch (type) {
case IDCR1: /* Indirect via SDRAM0_CFGADDR/DDR0_CFGDATA */
mtdcr(SDRAM0_CFGADDR, ppc4xx_reg[i].address);
value = mfdcr(SDRAM0_CFGDATA);
break;
case IDCR2: /* Indirect via EBC0_CFGADDR/EBC0_CFGDATA */
mtdcr(EBC0_CFGADDR, ppc4xx_reg[i].address);
value = mfdcr(EBC0_CFGDATA);
break;
case IDCR5: /* Indirect via CPR0_CFGADDR/CPR0_CFGDATA */
mtdcr(CPR0_CFGADDR, ppc4xx_reg[i].address);
value = mfdcr(CPR0_CFGDATA);
break;
case IDCR6: /* Indirect via SDR0_CFGADDR/SDR0_CFGDATA */
mtdcr(SDR0_CFGADDR, ppc4xx_reg[i].address);
value = mfdcr(SDR0_CFGDATA);
break;
case MM: /* Directly Accessed MMIO Register */
value = in_be32((const volatile unsigned __iomem *)
ppc4xx_reg[i].address);
break;
default:
printf("\nERROR: struct entry %d: unknown register"
"type\n", i);
break;
}
printf("0x%08x %-16s: 0x%08x\n",ppc4xx_reg[i].address,
ppc4xx_reg[i].name, value);
}
}

View File

@ -1,13 +0,0 @@
/* Copyright MontaVista Software Incorporated, 2000 */
#include <config.h>
.section .resetvec,"ax"
#if defined(CONFIG_440)
b _start_440
#else
#if defined(CONFIG_BOOT_PCI) && (defined(CONFIG_TARGET_MIP405) \
|| defined(CONFIG_TARGET_MIP405T))
b _start_pci
#else
b _start
#endif
#endif

View File

@ -1,458 +0,0 @@
/*
* (C) Copyright 2005-2007
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2006
* DAVE Srl <www.dave-tech.it>
*
* (C) Copyright 2002-2004
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/ppc4xx.h>
#include <asm/processor.h>
#include "sdram.h"
#include "ecc.h"
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_SDRAM_BANK0
#ifndef CONFIG_440
#ifndef CONFIG_SYS_SDRAM_TABLE
sdram_conf_t mb0cf[] = {
{(128 << 20), 13, 0x000A4001}, /* (0-128MB) Address Mode 3, 13x10(4) */
{(64 << 20), 13, 0x00084001}, /* (0-64MB) Address Mode 3, 13x9(4) */
{(32 << 20), 12, 0x00062001}, /* (0-32MB) Address Mode 2, 12x9(4) */
{(16 << 20), 12, 0x00046001}, /* (0-16MB) Address Mode 4, 12x8(4) */
{(4 << 20), 11, 0x00008001}, /* (0-4MB) Address Mode 5, 11x8(2) */
};
#else
sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
#endif
#define N_MB0CF (ARRAY_SIZE(mb0cf))
#ifdef CONFIG_SYS_SDRAM_CASL
static ulong ns2clks(ulong ns)
{
ulong bus_period_x_10 = ONE_BILLION / (get_bus_freq(0) / 10);
return ((ns * 10) + bus_period_x_10) / bus_period_x_10;
}
#endif /* CONFIG_SYS_SDRAM_CASL */
static ulong compute_sdtr1(ulong speed)
{
#ifdef CONFIG_SYS_SDRAM_CASL
ulong tmp;
ulong sdtr1 = 0;
/* CASL */
if (CONFIG_SYS_SDRAM_CASL < 2)
sdtr1 |= (1 << SDRAM0_TR_CASL);
else
if (CONFIG_SYS_SDRAM_CASL > 4)
sdtr1 |= (3 << SDRAM0_TR_CASL);
else
sdtr1 |= ((CONFIG_SYS_SDRAM_CASL-1) << SDRAM0_TR_CASL);
/* PTA */
tmp = ns2clks(CONFIG_SYS_SDRAM_PTA);
if ((tmp >= 2) && (tmp <= 4))
sdtr1 |= ((tmp-1) << SDRAM0_TR_PTA);
else
sdtr1 |= ((4-1) << SDRAM0_TR_PTA);
/* CTP */
tmp = ns2clks(CONFIG_SYS_SDRAM_CTP);
if ((tmp >= 2) && (tmp <= 4))
sdtr1 |= ((tmp-1) << SDRAM0_TR_CTP);
else
sdtr1 |= ((4-1) << SDRAM0_TR_CTP);
/* LDF */
tmp = ns2clks(CONFIG_SYS_SDRAM_LDF);
if ((tmp >= 2) && (tmp <= 4))
sdtr1 |= ((tmp-1) << SDRAM0_TR_LDF);
else
sdtr1 |= ((2-1) << SDRAM0_TR_LDF);
/* RFTA */
tmp = ns2clks(CONFIG_SYS_SDRAM_RFTA);
if ((tmp >= 4) && (tmp <= 10))
sdtr1 |= ((tmp-4) << SDRAM0_TR_RFTA);
else
sdtr1 |= ((10-4) << SDRAM0_TR_RFTA);
/* RCD */
tmp = ns2clks(CONFIG_SYS_SDRAM_RCD);
if ((tmp >= 2) && (tmp <= 4))
sdtr1 |= ((tmp-1) << SDRAM0_TR_RCD);
else
sdtr1 |= ((4-1) << SDRAM0_TR_RCD);
return sdtr1;
#else /* CONFIG_SYS_SDRAM_CASL */
/*
* If no values are configured in the board config file
* use the default values, which seem to be ok for most
* boards.
*
* REMARK:
* For new board ports we strongly recommend to define the
* correct values for the used SDRAM chips in your board
* config file (see PPChameleonEVB.h)
*/
if (speed > 100000000) {
/*
* 133 MHz SDRAM
*/
return 0x01074015;
} else {
/*
* default: 100 MHz SDRAM
*/
return 0x0086400d;
}
#endif /* CONFIG_SYS_SDRAM_CASL */
}
/* refresh is expressed in ms */
static ulong compute_rtr(ulong speed, ulong rows, ulong refresh)
{
#ifdef CONFIG_SYS_SDRAM_CASL
ulong tmp;
tmp = ((refresh*1000*1000) / (1 << rows)) * (speed / 1000);
tmp /= 1000000;
return ((tmp & 0x00003FF8) << 16);
#else /* CONFIG_SYS_SDRAM_CASL */
if (speed > 100000000) {
/*
* 133 MHz SDRAM
*/
return 0x07f00000;
} else {
/*
* default: 100 MHz SDRAM
*/
return 0x05f00000;
}
#endif /* CONFIG_SYS_SDRAM_CASL */
}
/*
* Autodetect onboard SDRAM on 405 platforms
*/
int dram_init(void)
{
ulong speed;
ulong sdtr1;
int i;
/*
* Determine SDRAM speed
*/
speed = get_bus_freq(0); /* parameter not used on ppc4xx */
/*
* sdtr1 (register SDRAM0_TR) must take into account timings listed
* in SDRAM chip datasheet. rtr (register SDRAM0_RTR) must take into
* account actual SDRAM size. So we can set up sdtr1 according to what
* is specified in board configuration file while rtr dependds on SDRAM
* size we are assuming before detection.
*/
sdtr1 = compute_sdtr1(speed);
for (i=0; i<N_MB0CF; i++) {
/*
* Disable memory controller.
*/
mtsdram(SDRAM0_CFG, 0x00000000);
/*
* Set MB0CF for bank 0.
*/
mtsdram(SDRAM0_B0CR, mb0cf[i].reg);
mtsdram(SDRAM0_TR, sdtr1);
mtsdram(SDRAM0_RTR, compute_rtr(speed, mb0cf[i].rows, 64));
udelay(200);
/*
* Set memory controller options reg, MCOPT1.
* Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
* read/prefetch.
*/
mtsdram(SDRAM0_CFG, 0x80800000);
udelay(10000);
if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
phys_size_t size = mb0cf[i].size;
/*
* OK, size detected. Enable second bank if
* defined (assumes same type as bank 0)
*/
#ifdef CONFIG_SDRAM_BANK1
mtsdram(SDRAM0_CFG, 0x00000000);
mtsdram(SDRAM0_B1CR, mb0cf[i].size | mb0cf[i].reg);
mtsdram(SDRAM0_CFG, 0x80800000);
udelay(10000);
/*
* Check if 2nd bank is really available.
* If the size not equal to the size of the first
* bank, then disable the 2nd bank completely.
*/
if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size) !=
mb0cf[i].size) {
mtsdram(SDRAM0_B1CR, 0);
mtsdram(SDRAM0_CFG, 0);
} else {
/*
* We have two identical banks, so the size
* is twice the bank size
*/
size = 2 * size;
}
#endif
/*
* OK, size detected -> all done
*/
gd->ram_size = size;
return 0;
}
}
return -ENXIO;
}
#else /* CONFIG_440 */
/*
* Define some default values. Those can be overwritten in the
* board config file.
*/
#ifndef CONFIG_SYS_SDRAM_TABLE
sdram_conf_t mb0cf[] = {
{(256 << 20), 13, 0x000C4001}, /* 256MB mode 3, 13x10(4) */
{(128 << 20), 13, 0x000A4001}, /* 128MB mode 3, 13x10(4) */
{(64 << 20), 12, 0x00082001} /* 64MB mode 2, 12x9(4) */
};
#else
sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
#endif
#ifndef CONFIG_SYS_SDRAM0_TR0
#define CONFIG_SYS_SDRAM0_TR0 0x41094012
#endif
#ifndef CONFIG_SYS_SDRAM0_WDDCTR
#define CONFIG_SYS_SDRAM0_WDDCTR 0x00000000 /* wrcp=0 dcd=0 */
#endif
#ifndef CONFIG_SYS_SDRAM0_RTR
#define CONFIG_SYS_SDRAM0_RTR 0x04100000 /* 7.8us @ 133MHz PLB */
#endif
#ifndef CONFIG_SYS_SDRAM0_CFG0
#define CONFIG_SYS_SDRAM0_CFG0 0x82000000 /* DCEN=1, PMUD=0, 64-bit */
#endif
#define N_MB0CF (ARRAY_SIZE(mb0cf))
#define NUM_TRIES 64
#define NUM_READS 10
static void sdram_tr1_set(int ram_address, int* tr1_value)
{
int i;
int j, k;
volatile unsigned int* ram_pointer = (unsigned int *)ram_address;
int first_good = -1, last_bad = 0x1ff;
unsigned long test[NUM_TRIES] = {
0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 };
/* go through all possible SDRAM0_TR1[RDCT] values */
for (i=0; i<=0x1ff; i++) {
/* set the current value for TR1 */
mtsdram(SDRAM0_TR1, (0x80800800 | i));
/* write values */
for (j=0; j<NUM_TRIES; j++) {
ram_pointer[j] = test[j];
/* clear any cache at ram location */
__asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
}
/* read values back */
for (j=0; j<NUM_TRIES; j++) {
for (k=0; k<NUM_READS; k++) {
/* clear any cache at ram location */
__asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
if (ram_pointer[j] != test[j])
break;
}
/* read error */
if (k != NUM_READS)
break;
}
/* we have a SDRAM0_TR1[RDCT] that is part of the window */
if (j == NUM_TRIES) {
if (first_good == -1)
first_good = i; /* found beginning of window */
} else { /* bad read */
/* if we have not had a good read then don't care */
if (first_good != -1) {
/* first failure after a good read */
last_bad = i-1;
break;
}
}
}
/* return the current value for TR1 */
*tr1_value = (first_good + last_bad) / 2;
}
/*
* Autodetect onboard DDR SDRAM on 440 platforms
*
* NOTE: Some of the hardcoded values are hardware dependant,
* so this should be extended for other future boards
* using this routine!
*/
int dram_init(void)
{
int i;
int tr1_bank1;
#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
defined(CONFIG_440GR) || defined(CONFIG_440SP)
/*
* Soft-reset SDRAM controller.
*/
mtsdr(SDR0_SRST, SDR0_SRST_DMC);
mtsdr(SDR0_SRST, 0x00000000);
#endif
for (i=0; i<N_MB0CF; i++) {
/*
* Disable memory controller.
*/
mtsdram(SDRAM0_CFG0, 0x00000000);
/*
* Setup some default
*/
mtsdram(SDRAM0_UABBA, 0x00000000); /* ubba=0 (default) */
mtsdram(SDRAM0_SLIO, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
mtsdram(SDRAM0_DEVOPT, 0x00000000); /* dll=0 ds=0 (normal) */
mtsdram(SDRAM0_WDDCTR, CONFIG_SYS_SDRAM0_WDDCTR);
mtsdram(SDRAM0_CLKTR, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
/*
* Following for CAS Latency = 2.5 @ 133 MHz PLB
*/
mtsdram(SDRAM0_B0CR, mb0cf[i].reg);
mtsdram(SDRAM0_TR0, CONFIG_SYS_SDRAM0_TR0);
mtsdram(SDRAM0_TR1, 0x80800800); /* SS=T2 SL=STAGE 3 CD=1 CT=0x00*/
mtsdram(SDRAM0_RTR, CONFIG_SYS_SDRAM0_RTR);
mtsdram(SDRAM0_CFG1, 0x00000000); /* Self-refresh exit, disable PM*/
udelay(400); /* Delay 200 usecs (min) */
/*
* Enable the controller, then wait for DCEN to complete
*/
mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0);
udelay(10000);
if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
phys_size_t size = mb0cf[i].size;
/*
* Optimize TR1 to current hardware environment
*/
sdram_tr1_set(0x00000000, &tr1_bank1);
mtsdram(SDRAM0_TR1, (tr1_bank1 | 0x80800800));
/*
* OK, size detected. Enable second bank if
* defined (assumes same type as bank 0)
*/
#ifdef CONFIG_SDRAM_BANK1
mtsdram(SDRAM0_CFG0, 0);
mtsdram(SDRAM0_B1CR, mb0cf[i].size | mb0cf[i].reg);
mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0);
udelay(10000);
/*
* Check if 2nd bank is really available.
* If the size not equal to the size of the first
* bank, then disable the 2nd bank completely.
*/
if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size)
!= mb0cf[i].size) {
mtsdram(SDRAM0_CFG0, 0);
mtsdram(SDRAM0_B1CR, 0);
mtsdram(SDRAM0_CFG0, CONFIG_SYS_SDRAM0_CFG0);
udelay(10000);
} else {
/*
* We have two identical banks, so the size
* is twice the bank size
*/
size = 2 * size;
}
#endif
#ifdef CONFIG_SDRAM_ECC
ecc_init(0, size);
#endif
/*
* OK, size detected -> all done
*/
gd->ram_size = size;
return 0;
}
}
return -ENXIO; /* nothing found ! */
}
#endif /* CONFIG_440 */
#endif /* CONFIG_SDRAM_BANK0 */

View File

@ -1,60 +0,0 @@
/*
* (C) Copyright 2006
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2006
* DAVE Srl <www.dave-tech.it>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _SDRAM_H_
#define _SDRAM_H_
#include <config.h>
#define ONE_BILLION 1000000000
struct sdram_conf_s {
unsigned long size;
int rows;
unsigned long reg;
};
typedef struct sdram_conf_s sdram_conf_t;
/* Bitfields offsets */
#define SDRAM0_TR_CASL (31 - 8)
#define SDRAM0_TR_PTA (31 - 13)
#define SDRAM0_TR_CTP (31 - 15)
#define SDRAM0_TR_LDF (31 - 17)
#define SDRAM0_TR_RFTA (31 - 29)
#define SDRAM0_TR_RCD (31 - 31)
#ifdef CONFIG_SYS_SDRAM_CL
/* SDRAM timings [ns] according to AMCC/IBM names (see SDRAM_faq.doc) */
#define CONFIG_SYS_SDRAM_CASL CONFIG_SYS_SDRAM_CL
#define CONFIG_SYS_SDRAM_PTA CONFIG_SYS_SDRAM_tRP
#define CONFIG_SYS_SDRAM_CTP (CONFIG_SYS_SDRAM_tRC - CONFIG_SYS_SDRAM_tRCD - CONFIG_SYS_SDRAM_tRP)
#define CONFIG_SYS_SDRAM_LDF 0
#ifdef CONFIG_SYS_SDRAM_tRFC
#define CONFIG_SYS_SDRAM_RFTA CONFIG_SYS_SDRAM_tRFC
#else
#define CONFIG_SYS_SDRAM_RFTA CONFIG_SYS_SDRAM_tRC
#endif
#define CONFIG_SYS_SDRAM_RCD CONFIG_SYS_SDRAM_tRCD
#endif /* #ifdef CONFIG_SYS_SDRAM_CL */
/*
* Some defines for the 440 DDR controller
*/
#define SDRAM_CFG0_DC_EN 0x80000000 /* SDRAM Controller Enable */
#define SDRAM_CFG0_MEMCHK 0x30000000 /* Memory data error checking mask*/
#define SDRAM_CFG0_MEMCHK_NON 0x00000000 /* No ECC generation */
#define SDRAM_CFG0_MEMCHK_GEN 0x20000000 /* ECC generation */
#define SDRAM_CFG0_MEMCHK_CHK 0x30000000 /* ECC generation and checking */
#define SDRAM_CFG0_DRAMWDTH 0x02000000 /* DRAM width mask */
#define SDRAM_CFG0_DRAMWDTH_32 0x00000000 /* 32 bits */
#define SDRAM_CFG0_DRAMWDTH_64 0x02000000 /* 64 bits */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +0,0 @@
/*
* Copyright (C) 2013 Stefan Roese <sr@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <spl.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* Return selected boot device. On PPC4xx its only NOR flash right now.
*/
u32 spl_boot_device(void)
{
return BOOT_DEVICE_NOR;
}
/*
* SPL version of board_init_f()
*/
void board_init_f(ulong bootflag)
{
/*
* First we need to initialize the SDRAM, so that the real
* U-Boot or the OS (Linux) can be loaded
*/
dram_init();
/* Clear bss */
memset(__bss_start, '\0', __bss_end - __bss_start);
/*
* Init global_data pointer. Has to be done before calling
* get_clocks(), as it stores some clock values into gd needed
* later on in the serial driver.
*/
/* Pointer is writable since we allocated a register for it */
gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET);
/* Clear initial global data */
memset((void *)gd, 0, sizeof(gd_t));
/*
* get_clocks() needs to be called so that the serial driver
* works correctly
*/
get_clocks();
/*
* Do rudimental console / serial setup
*/
preloader_console_init();
/*
* Call board_init_r() (SPL framework version) to load and boot
* real U-Boot or OS
*/
board_init_r(NULL, 0);
/* Does not return!!! */
}

File diff suppressed because it is too large Load Diff

View File

@ -1,336 +0,0 @@
/*
* (C) Copyright 2007
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#if defined(CONFIG_440)
#include <asm/ppc440.h>
#include <asm/cache.h>
#include <asm/io.h>
#include <asm/mmu.h>
typedef struct region {
u64 base;
u32 size;
u32 tlb_word2_i_value;
} region_t;
void remove_tlb(u32 vaddr, u32 size)
{
int i;
u32 tlb_word0_value;
u32 tlb_vaddr;
u32 tlb_size = 0;
for (i=0; i<PPC4XX_TLB_SIZE; i++) {
tlb_word0_value = mftlb1(i);
tlb_vaddr = TLB_WORD0_EPN_DECODE(tlb_word0_value);
if (((tlb_word0_value & TLB_WORD0_V_MASK) == TLB_WORD0_V_ENABLE) &&
(tlb_vaddr >= vaddr)) {
/*
* TLB is enabled and start address is lower or equal
* than the area we are looking for. Now we only have
* to check the size/end address for a match.
*/
switch (tlb_word0_value & TLB_WORD0_SIZE_MASK) {
case TLB_WORD0_SIZE_1KB:
tlb_size = 1 << 10;
break;
case TLB_WORD0_SIZE_4KB:
tlb_size = 4 << 10;
break;
case TLB_WORD0_SIZE_16KB:
tlb_size = 16 << 10;
break;
case TLB_WORD0_SIZE_64KB:
tlb_size = 64 << 10;
break;
case TLB_WORD0_SIZE_256KB:
tlb_size = 256 << 10;
break;
case TLB_WORD0_SIZE_1MB:
tlb_size = 1 << 20;
break;
case TLB_WORD0_SIZE_16MB:
tlb_size = 16 << 20;
break;
case TLB_WORD0_SIZE_256MB:
tlb_size = 256 << 20;
break;
}
/*
* Now check the end-address if it's in the range
*/
if ((tlb_vaddr + tlb_size - 1) <= (vaddr + size - 1))
/*
* Found a TLB in the range.
* Disable it by writing 0 to tlb0 word.
*/
mttlb1(i, 0);
}
}
/* Execute an ISYNC instruction so that the new TLB entry takes effect */
asm("isync");
}
/*
* Change the I attribute (cache inhibited) of a TLB or multiple TLB's.
* This function is used to either turn cache on or off in a specific
* memory area.
*/
void change_tlb(u32 vaddr, u32 size, u32 tlb_word2_i_value)
{
int i;
u32 tlb_word0_value;
u32 tlb_word2_value;
u32 tlb_vaddr;
u32 tlb_size = 0;
for (i=0; i<PPC4XX_TLB_SIZE; i++) {
tlb_word0_value = mftlb1(i);
tlb_vaddr = TLB_WORD0_EPN_DECODE(tlb_word0_value);
if (((tlb_word0_value & TLB_WORD0_V_MASK) == TLB_WORD0_V_ENABLE) &&
(tlb_vaddr >= vaddr)) {
/*
* TLB is enabled and start address is lower or equal
* than the area we are looking for. Now we only have
* to check the size/end address for a match.
*/
switch (tlb_word0_value & TLB_WORD0_SIZE_MASK) {
case TLB_WORD0_SIZE_1KB:
tlb_size = 1 << 10;
break;
case TLB_WORD0_SIZE_4KB:
tlb_size = 4 << 10;
break;
case TLB_WORD0_SIZE_16KB:
tlb_size = 16 << 10;
break;
case TLB_WORD0_SIZE_64KB:
tlb_size = 64 << 10;
break;
case TLB_WORD0_SIZE_256KB:
tlb_size = 256 << 10;
break;
case TLB_WORD0_SIZE_1MB:
tlb_size = 1 << 20;
break;
case TLB_WORD0_SIZE_16MB:
tlb_size = 16 << 20;
break;
case TLB_WORD0_SIZE_256MB:
tlb_size = 256 << 20;
break;
}
/*
* Now check the end-address if it's in the range
*/
if (((tlb_vaddr + tlb_size - 1) <= (vaddr + size - 1)) ||
((tlb_vaddr < (vaddr + size - 1)) &&
((tlb_vaddr + tlb_size - 1) > (vaddr + size - 1)))) {
/*
* Found a TLB in the range.
* Change cache attribute in tlb2 word.
*/
tlb_word2_value =
TLB_WORD2_U0_DISABLE | TLB_WORD2_U1_DISABLE |
TLB_WORD2_U2_DISABLE | TLB_WORD2_U3_DISABLE |
TLB_WORD2_W_DISABLE | tlb_word2_i_value |
TLB_WORD2_M_DISABLE | TLB_WORD2_G_DISABLE |
TLB_WORD2_E_DISABLE | TLB_WORD2_UX_ENABLE |
TLB_WORD2_UW_ENABLE | TLB_WORD2_UR_ENABLE |
TLB_WORD2_SX_ENABLE | TLB_WORD2_SW_ENABLE |
TLB_WORD2_SR_ENABLE;
/*
* Now either flush or invalidate the dcache
*/
if (tlb_word2_i_value)
flush_dcache();
else
invalidate_dcache();
mttlb3(i, tlb_word2_value);
asm("iccci 0,0");
}
}
}
/* Execute an ISYNC instruction so that the new TLB entry takes effect */
asm("isync");
}
static int add_tlb_entry(u64 phys_addr,
u32 virt_addr,
u32 tlb_word0_size_value,
u32 tlb_word2_i_value)
{
int i;
unsigned long tlb_word0_value;
unsigned long tlb_word1_value;
unsigned long tlb_word2_value;
/* First, find the index of a TLB entry not being used */
for (i=0; i<PPC4XX_TLB_SIZE; i++) {
tlb_word0_value = mftlb1(i);
if ((tlb_word0_value & TLB_WORD0_V_MASK) == TLB_WORD0_V_DISABLE)
break;
}
if (i >= PPC4XX_TLB_SIZE)
return -1;
/* Second, create the TLB entry */
tlb_word0_value = TLB_WORD0_EPN_ENCODE(virt_addr) | TLB_WORD0_V_ENABLE |
TLB_WORD0_TS_0 | tlb_word0_size_value;
tlb_word1_value = TLB_WORD1_RPN_ENCODE((u32)phys_addr) |
TLB_WORD1_ERPN_ENCODE(phys_addr >> 32);
tlb_word2_value = TLB_WORD2_U0_DISABLE | TLB_WORD2_U1_DISABLE |
TLB_WORD2_U2_DISABLE | TLB_WORD2_U3_DISABLE |
TLB_WORD2_W_DISABLE | tlb_word2_i_value |
TLB_WORD2_M_DISABLE | TLB_WORD2_G_DISABLE |
TLB_WORD2_E_DISABLE | TLB_WORD2_UX_ENABLE |
TLB_WORD2_UW_ENABLE | TLB_WORD2_UR_ENABLE |
TLB_WORD2_SX_ENABLE | TLB_WORD2_SW_ENABLE |
TLB_WORD2_SR_ENABLE;
/* Wait for all memory accesses to complete */
sync();
/* Third, add the TLB entries */
mttlb1(i, tlb_word0_value);
mttlb2(i, tlb_word1_value);
mttlb3(i, tlb_word2_value);
/* Execute an ISYNC instruction so that the new TLB entry takes effect */
asm("isync");
return 0;
}
static void program_tlb_addr(u64 phys_addr,
u32 virt_addr,
u32 mem_size,
u32 tlb_word2_i_value)
{
int rc;
int tlb_i;
tlb_i = tlb_word2_i_value;
while (mem_size != 0) {
rc = 0;
/* Add the TLB entries in to map the region. */
if (((phys_addr & TLB_256MB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_256MB_SIZE)) {
/* Add a 256MB TLB entry */
if ((rc = add_tlb_entry(phys_addr, virt_addr,
TLB_WORD0_SIZE_256MB, tlb_i)) == 0) {
mem_size -= TLB_256MB_SIZE;
phys_addr += TLB_256MB_SIZE;
virt_addr += TLB_256MB_SIZE;
}
} else if (((phys_addr & TLB_16MB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_16MB_SIZE)) {
/* Add a 16MB TLB entry */
if ((rc = add_tlb_entry(phys_addr, virt_addr,
TLB_WORD0_SIZE_16MB, tlb_i)) == 0) {
mem_size -= TLB_16MB_SIZE;
phys_addr += TLB_16MB_SIZE;
virt_addr += TLB_16MB_SIZE;
}
} else if (((phys_addr & TLB_1MB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_1MB_SIZE)) {
/* Add a 1MB TLB entry */
if ((rc = add_tlb_entry(phys_addr, virt_addr,
TLB_WORD0_SIZE_1MB, tlb_i)) == 0) {
mem_size -= TLB_1MB_SIZE;
phys_addr += TLB_1MB_SIZE;
virt_addr += TLB_1MB_SIZE;
}
} else if (((phys_addr & TLB_256KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_256KB_SIZE)) {
/* Add a 256KB TLB entry */
if ((rc = add_tlb_entry(phys_addr, virt_addr,
TLB_WORD0_SIZE_256KB, tlb_i)) == 0) {
mem_size -= TLB_256KB_SIZE;
phys_addr += TLB_256KB_SIZE;
virt_addr += TLB_256KB_SIZE;
}
} else if (((phys_addr & TLB_64KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_64KB_SIZE)) {
/* Add a 64KB TLB entry */
if ((rc = add_tlb_entry(phys_addr, virt_addr,
TLB_WORD0_SIZE_64KB, tlb_i)) == 0) {
mem_size -= TLB_64KB_SIZE;
phys_addr += TLB_64KB_SIZE;
virt_addr += TLB_64KB_SIZE;
}
} else if (((phys_addr & TLB_16KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_16KB_SIZE)) {
/* Add a 16KB TLB entry */
if ((rc = add_tlb_entry(phys_addr, virt_addr,
TLB_WORD0_SIZE_16KB, tlb_i)) == 0) {
mem_size -= TLB_16KB_SIZE;
phys_addr += TLB_16KB_SIZE;
virt_addr += TLB_16KB_SIZE;
}
} else if (((phys_addr & TLB_4KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_4KB_SIZE)) {
/* Add a 4KB TLB entry */
if ((rc = add_tlb_entry(phys_addr, virt_addr,
TLB_WORD0_SIZE_4KB, tlb_i)) == 0) {
mem_size -= TLB_4KB_SIZE;
phys_addr += TLB_4KB_SIZE;
virt_addr += TLB_4KB_SIZE;
}
} else if (((phys_addr & TLB_1KB_ALIGN_MASK) == phys_addr) &&
(mem_size >= TLB_1KB_SIZE)) {
/* Add a 1KB TLB entry */
if ((rc = add_tlb_entry(phys_addr, virt_addr,
TLB_WORD0_SIZE_1KB, tlb_i)) == 0) {
mem_size -= TLB_1KB_SIZE;
phys_addr += TLB_1KB_SIZE;
virt_addr += TLB_1KB_SIZE;
}
} else {
printf("ERROR: no TLB size exists for the base address 0x%llx.\n",
phys_addr);
}
if (rc != 0)
printf("ERROR: no TLB entries available for the base addr 0x%llx.\n",
phys_addr);
}
return;
}
/*
* Program one (or multiple) TLB entries for one memory region
*
* Common usage for boards with SDRAM DIMM modules to dynamically
* configure the TLB's for the SDRAM
*/
void program_tlb(u64 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value)
{
region_t region_array;
region_array.base = phys_addr;
region_array.size = size;
region_array.tlb_word2_i_value = tlb_word2_i_value; /* en-/disable cache */
/* Call the routine to add in the tlb entries for the memory regions */
program_tlb_addr(region_array.base, virt_addr, region_array.size,
region_array.tlb_word2_i_value);
return;
}
#endif /* CONFIG_440 */

View File

@ -1,392 +0,0 @@
/*
* linux/arch/powerpc/kernel/traps.c
*
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Modified by Cort Dougan (cort@cs.nmt.edu)
* and Paul Mackerras (paulus@cs.anu.edu.au)
*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*
* This file handles the architecture-dependent parts of hardware exceptions
*/
#include <common.h>
#include <command.h>
#include <kgdb.h>
#include <asm/processor.h>
DECLARE_GLOBAL_DATA_PTR;
/* Returns 0 if exception not found and fixup otherwise. */
extern unsigned long search_exception_table(unsigned long);
/* THIS NEEDS CHANGING to use the board info structure.
*/
#define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize)
static __inline__ unsigned long get_esr(void)
{
unsigned long val;
#if defined(CONFIG_440)
asm volatile("mfspr %0, 0x03e" : "=r" (val) :);
#else
asm volatile("mfesr %0" : "=r" (val) :);
#endif
return val;
}
#define ESR_MCI 0x80000000
#define ESR_PIL 0x08000000
#define ESR_PPR 0x04000000
#define ESR_PTR 0x02000000
#define ESR_DST 0x00800000
#define ESR_DIZ 0x00400000
#define ESR_U0F 0x00008000
#if defined(CONFIG_CMD_BEDBUG)
extern void do_bedbug_breakpoint(struct pt_regs *);
#endif
/*
* Trap & Exception support
*/
static void print_backtrace(unsigned long *sp)
{
int cnt = 0;
unsigned long i;
printf("Call backtrace: ");
while (sp) {
if ((uint)sp > END_OF_MEM)
break;
i = sp[1];
if (cnt++ % 7 == 0)
printf("\n");
printf("%08lX ", i);
if (cnt > 32) break;
sp = (unsigned long *)*sp;
}
printf("\n");
}
void show_regs(struct pt_regs *regs)
{
int i;
printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DEAR: %08lX\n",
regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
regs->msr&MSR_IR ? 1 : 0,
regs->msr&MSR_DR ? 1 : 0);
printf("\n");
for (i = 0; i < 32; i++) {
if ((i % 8) == 0) {
printf("GPR%02d: ", i);
}
printf("%08lX ", regs->gpr[i]);
if ((i % 8) == 7) {
printf("\n");
}
}
}
static void _exception(int signr, struct pt_regs *regs)
{
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("Exception");
}
void MachineCheckException(struct pt_regs *regs)
{
unsigned long fixup, val;
#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
u32 value2;
int corr_ecc = 0;
int uncorr_ecc = 0;
#endif
if ((fixup = search_exception_table(regs->nip)) != 0) {
regs->nip = fixup;
val = mfspr(MCSR);
/* Clear MCSR */
mtspr(SPRN_MCSR, val);
return;
}
#if defined(CONFIG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
printf("Machine Check Exception.\n");
printf("Caused by (from msr): ");
printf("regs %p ", regs);
val = get_esr();
#if !defined(CONFIG_440) && !defined(CONFIG_405EX)
if (val& ESR_IMCP) {
printf("Instruction");
mtspr(ESR, val & ~ESR_IMCP);
} else {
printf("Data");
}
printf(" machine check.\n");
#elif defined(CONFIG_440) || defined(CONFIG_405EX)
if (val& ESR_IMCP){
printf("Instruction Synchronous Machine Check exception\n");
mtspr(SPRN_ESR, val & ~ESR_IMCP);
} else {
val = mfspr(MCSR);
if (val & MCSR_IB)
printf("Instruction Read PLB Error\n");
#if defined(CONFIG_440)
if (val & MCSR_DRB)
printf("Data Read PLB Error\n");
if (val & MCSR_DWB)
printf("Data Write PLB Error\n");
#else
if (val & MCSR_DB)
printf("Data PLB Error\n");
#endif
if (val & MCSR_TLBP)
printf("TLB Parity Error\n");
if (val & MCSR_ICP){
/*flush_instruction_cache(); */
printf("I-Cache Parity Error\n");
}
if (val & MCSR_DCSP)
printf("D-Cache Search Parity Error\n");
if (val & MCSR_DCFP)
printf("D-Cache Flush Parity Error\n");
if (val & MCSR_IMPE)
printf("Machine Check exception is imprecise\n");
/* Clear MCSR */
mtspr(SPRN_MCSR, val);
}
#if defined(CONFIG_DDR_ECC) && defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
/*
* Read and print ECC status register/info:
* The faulting address is only known upon uncorrectable ECC
* errors.
*/
mfsdram(SDRAM_ECCES, val);
if (val & SDRAM_ECCES_CE)
printf("ECC: Correctable error\n");
if (val & SDRAM_ECCES_UE) {
printf("ECC: Uncorrectable error at 0x%02x%08x\n",
mfdcr(SDRAM_ERRADDULL), mfdcr(SDRAM_ERRADDLLL));
}
#endif /* CONFIG_DDR_ECC ... */
#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
mfsdram(DDR0_00, val) ;
printf("DDR0: DDR0_00 %lx\n", val);
val = (val >> 16) & 0xff;
if (val & 0x80)
printf("DDR0: At least one interrupt active\n");
if (val & 0x40)
printf("DDR0: DRAM initialization complete.\n");
if (val & 0x20) {
printf("DDR0: Multiple uncorrectable ECC events.\n");
uncorr_ecc = 1;
}
if (val & 0x10) {
printf("DDR0: Single uncorrectable ECC event.\n");
uncorr_ecc = 1;
}
if (val & 0x08) {
printf("DDR0: Multiple correctable ECC events.\n");
corr_ecc = 1;
}
if (val & 0x04) {
printf("DDR0: Single correctable ECC event.\n");
corr_ecc = 1;
}
if (val & 0x02)
printf("Multiple accesses outside the defined"
" physical memory space detected\n");
if (val & 0x01)
printf("DDR0: Single access outside the defined"
" physical memory space detected.\n");
mfsdram(DDR0_01, val);
val = (val >> 8) & 0x7;
switch (val ) {
case 0:
printf("DDR0: Write Out-of-Range command\n");
break;
case 1:
printf("DDR0: Read Out-of-Range command\n");
break;
case 2:
printf("DDR0: Masked write Out-of-Range command\n");
break;
case 4:
printf("DDR0: Wrap write Out-of-Range command\n");
break;
case 5:
printf("DDR0: Wrap read Out-of-Range command\n");
break;
default:
mfsdram(DDR0_01, value2);
printf("DDR0: No DDR0 error know 0x%lx %x\n", val, value2);
}
mfsdram(DDR0_23, val);
if (((val >> 16) & 0xff) && corr_ecc)
printf("DDR0: Syndrome for correctable ECC event 0x%lx\n",
(val >> 16) & 0xff);
mfsdram(DDR0_23, val);
if (((val >> 8) & 0xff) && uncorr_ecc)
printf("DDR0: Syndrome for uncorrectable ECC event 0x%lx\n",
(val >> 8) & 0xff);
mfsdram(DDR0_33, val);
if (val)
printf("DDR0: Address of command that caused an "
"Out-of-Range interrupt %lx\n", val);
mfsdram(DDR0_34, val);
if (val && uncorr_ecc)
printf("DDR0: Address of uncorrectable ECC event %lx\n", val);
mfsdram(DDR0_35, val);
if (val && uncorr_ecc)
printf("DDR0: Address of uncorrectable ECC event %lx\n", val);
mfsdram(DDR0_36, val);
if (val && uncorr_ecc)
printf("DDR0: Data of uncorrectable ECC event 0x%08lx\n", val);
mfsdram(DDR0_37, val);
if (val && uncorr_ecc)
printf("DDR0: Data of uncorrectable ECC event 0x%08lx\n", val);
mfsdram(DDR0_38, val);
if (val && corr_ecc)
printf("DDR0: Address of correctable ECC event %lx\n", val);
mfsdram(DDR0_39, val);
if (val && corr_ecc)
printf("DDR0: Address of correctable ECC event %lx\n", val);
mfsdram(DDR0_40, val);
if (val && corr_ecc)
printf("DDR0: Data of correctable ECC event 0x%08lx\n", val);
mfsdram(DDR0_41, val);
if (val && corr_ecc)
printf("DDR0: Data of correctable ECC event 0x%08lx\n", val);
#endif /* CONFIG_440EPX */
#endif /* CONFIG_440 */
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("machine check");
}
void AlignmentException(struct pt_regs *regs)
{
#if defined(CONFIG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("Alignment Exception");
}
void ProgramCheckException(struct pt_regs *regs)
{
long esr_val;
#if defined(CONFIG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
show_regs(regs);
esr_val = get_esr();
if( esr_val & ESR_PIL )
printf( "** Illegal Instruction **\n" );
else if( esr_val & ESR_PPR )
printf( "** Privileged Instruction **\n" );
else if( esr_val & ESR_PTR )
printf( "** Trap Instruction **\n" );
print_backtrace((unsigned long *)regs->gpr[1]);
panic("Program Check Exception");
}
void DecrementerPITException(struct pt_regs *regs)
{
/*
* Reset PIT interrupt
*/
mtspr(SPRN_TSR, 0x08000000);
/*
* Call timer_interrupt routine in interrupts.c
*/
timer_interrupt(NULL);
}
void UnknownException(struct pt_regs *regs)
{
#if defined(CONFIG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
regs->nip, regs->msr, regs->trap);
_exception(0, regs);
}
void DebugException(struct pt_regs *regs)
{
printf("Debugger trap at @ %lx\n", regs->nip );
show_regs(regs);
#if defined(CONFIG_CMD_BEDBUG)
do_bedbug_breakpoint( regs );
#endif
}
/* Probe an address by reading. If not present, return -1, otherwise
* return 0.
*/
int
addr_probe(uint *addr)
{
#if 0
int retval;
__asm__ __volatile__( \
"1: lwz %0,0(%1)\n" \
" eieio\n" \
" li %0,0\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
"3: li %0,-1\n" \
" b 2b\n" \
".section __ex_table,\"a\"\n" \
" .align 2\n" \
" .long 1b,3b\n" \
".text" \
: "=r" (retval) : "r"(addr));
return (retval);
#endif
return 0;
}

View File

@ -1,61 +0,0 @@
/*
* Copyright 2012-2013 Stefan Roese <sr@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
MEMORY
{
sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR,
LENGTH = CONFIG_SPL_BSS_MAX_SIZE
flash : ORIGIN = CONFIG_SPL_TEXT_BASE,
LENGTH = CONFIG_SYS_SPL_MAX_LEN
}
OUTPUT_ARCH(powerpc)
ENTRY(_start)
SECTIONS
{
#ifdef CONFIG_440
.bootpg 0xfffff000 :
{
arch/powerpc/cpu/ppc4xx/start.o (.bootpg)
/*
* PPC440 board need a board specific object with the
* TLB definitions. This needs to get included right after
* start.o, since the first shadow TLB only covers 4k
* of address space.
*/
CONFIG_BOARDDIR/init.o (.bootpg)
} > flash
#endif
.resetvec 0xFFFFFFFC :
{
KEEP(*(.resetvec))
} > flash
.text :
{
__start = .;
arch/powerpc/cpu/ppc4xx/start.o (.text)
CONFIG_BOARDDIR/init.o (.text)
*(.text*)
} > flash
. = ALIGN(4);
.data : { *(SORT_BY_ALIGNMENT(.data*)) } > flash
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > flash
.bss :
{
. = ALIGN(4);
__bss_start = .;
*(.bss*)
. = ALIGN(4);
__bss_end = .;
} > sdram
}

View File

@ -1,136 +0,0 @@
/*
* Copyright 2007-2009 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "config.h" /* CONFIG_BOARDDIR */
#ifndef RESET_VECTOR_ADDRESS
#ifdef CONFIG_RESET_VECTOR_ADDRESS
#define RESET_VECTOR_ADDRESS CONFIG_RESET_VECTOR_ADDRESS
#else
#define RESET_VECTOR_ADDRESS 0xfffffffc
#endif
#endif
OUTPUT_ARCH(powerpc)
PHDRS
{
text PT_LOAD;
bss PT_LOAD;
}
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = + SIZEOF_HEADERS;
.text :
{
*(.text*)
} :text
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
} :text
/* Read-write section, merged into data segment: */
. = (. + 0x00FF) & 0xFFFFFF00;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
_GOT2_TABLE_ = .;
KEEP(*(.got2))
KEEP(*(.got))
_FIXUP_TABLE_ = .;
KEEP(*(.fixup))
}
__got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
__fixup_entries = (. - _FIXUP_TABLE_) >> 2;
.data :
{
*(.data*)
*(.sdata*)
}
_edata = .;
PROVIDE (edata = .);
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
. = .;
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(256);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : {
*(.data.init)
. = ALIGN(256);
LONG(0) LONG(0) /* Extend u-boot.bin to here */
}
__init_end = .;
_end = .;
#ifndef CONFIG_SPL
#ifdef CONFIG_440
.bootpg RESET_VECTOR_ADDRESS - 0xffc :
{
arch/powerpc/cpu/ppc4xx/start.o (.bootpg)
/*
* PPC440 board need a board specific object with the
* TLB definitions. This needs to get included right after
* start.o, since the first shadow TLB only covers 4k
* of address space.
*/
#ifdef CONFIG_INIT_TLB
CONFIG_INIT_TLB (.bootpg)
#else
CONFIG_BOARDDIR/init.o (.bootpg)
#endif
} :text = 0xffff
#endif
.resetvec RESET_VECTOR_ADDRESS :
{
KEEP(*(.resetvec))
} :text = 0xffff
. = RESET_VECTOR_ADDRESS + 0x4;
/*
* Make sure that the bss segment isn't linked at 0x0, otherwise its
* address won't be updated during relocation fixups. Note that
* this is a temporary fix. Code to dynamically the fixup the bss
* location will be added in the future. When the bss relocation
* fixup code is present this workaround should be removed.
*/
#if (RESET_VECTOR_ADDRESS == 0xfffffffc)
. |= 0x10;
#endif
#endif /* CONFIG_SPL */
__bss_start = .;
.bss (NOLOAD) :
{
*(.bss*)
*(.sbss*)
*(COMMON)
} :bss
. = ALIGN(4);
__bss_end = . ;
PROVIDE (end = .);
}

View File

@ -1,163 +0,0 @@
/*
* (C) Copyright 2000-2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* (C) Copyright 2002 (440 port)
* Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com
*
* (C) Copyright 2003 (440GX port)
* Travis B. Sawyer, Sandburst Corporation, tsawyer@sandburst.com
*
* (C) Copyright 2008 (PPC440X05 port for Virtex 5 FX)
* Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@gmail.com
* Work supported by Qtechnology (htpp://qtec.com)
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <asm/processor.h>
#include <asm/interrupt.h>
#include <asm/ppc4xx.h>
#include <ppc_asm.tmpl>
#if (UIC_MAX > 3)
#define UICB0_ALL (UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI) | \
UIC_MASK(VECNUM_UIC2CI) | UIC_MASK(VECNUM_UIC2NCI) | \
UIC_MASK(VECNUM_UIC3CI) | UIC_MASK(VECNUM_UIC3NCI))
#elif (UIC_MAX > 2)
#define UICB0_ALL (UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI) | \
UIC_MASK(VECNUM_UIC2CI) | UIC_MASK(VECNUM_UIC2NCI))
#elif (UIC_MAX > 1)
#define UICB0_ALL (UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI))
#else
#define UICB0_ALL 0
#endif
u32 get_dcr(u16);
DECLARE_GLOBAL_DATA_PTR;
void pic_enable(void)
{
#if (UIC_MAX > 1)
/* Install the UIC1 handlers */
irq_install_handler(VECNUM_UIC1NCI, (void *)(void *)external_interrupt, 0);
irq_install_handler(VECNUM_UIC1CI, (void *)(void *)external_interrupt, 0);
#endif
#if (UIC_MAX > 2)
irq_install_handler(VECNUM_UIC2NCI, (void *)(void *)external_interrupt, 0);
irq_install_handler(VECNUM_UIC2CI, (void *)(void *)external_interrupt, 0);
#endif
#if (UIC_MAX > 3)
irq_install_handler(VECNUM_UIC3NCI, (void *)(void *)external_interrupt, 0);
irq_install_handler(VECNUM_UIC3CI, (void *)(void *)external_interrupt, 0);
#endif
}
/* Handler for UIC interrupt */
static void uic_interrupt(u32 uic_base, int vec_base)
{
u32 uic_msr;
u32 msr_shift;
int vec;
/*
* Read masked interrupt status register to determine interrupt source
*/
uic_msr = get_dcr(uic_base + UIC_MSR);
msr_shift = uic_msr;
vec = vec_base;
while (msr_shift != 0) {
if (msr_shift & 0x80000000)
interrupt_run_handler(vec);
/*
* Shift msr to next position and increment vector
*/
msr_shift <<= 1;
vec++;
}
}
/*
* Handle external interrupts
*/
void external_interrupt(struct pt_regs *regs)
{
u32 uic_msr;
/*
* Read masked interrupt status register to determine interrupt source
*/
uic_msr = mfdcr(UIC0MSR);
#if (UIC_MAX > 1)
if ((UIC_MASK(VECNUM_UIC1CI) & uic_msr) ||
(UIC_MASK(VECNUM_UIC1NCI) & uic_msr))
uic_interrupt(UIC1_DCR_BASE, 32);
#endif
#if (UIC_MAX > 2)
if ((UIC_MASK(VECNUM_UIC2CI) & uic_msr) ||
(UIC_MASK(VECNUM_UIC2NCI) & uic_msr))
uic_interrupt(UIC2_DCR_BASE, 64);
#endif
#if (UIC_MAX > 3)
if ((UIC_MASK(VECNUM_UIC3CI) & uic_msr) ||
(UIC_MASK(VECNUM_UIC3NCI) & uic_msr))
uic_interrupt(UIC3_DCR_BASE, 96);
#endif
mtdcr(UIC0SR, (uic_msr & UICB0_ALL));
if (uic_msr & ~(UICB0_ALL))
uic_interrupt(UIC0_DCR_BASE, 0);
return;
}
void pic_irq_ack(unsigned int vec)
{
if ((vec >= 0) && (vec < 32))
mtdcr(UIC0SR, UIC_MASK(vec));
else if ((vec >= 32) && (vec < 64))
mtdcr(UIC1SR, UIC_MASK(vec));
else if ((vec >= 64) && (vec < 96))
mtdcr(UIC2SR, UIC_MASK(vec));
else if (vec >= 96)
mtdcr(UIC3SR, UIC_MASK(vec));
}
/*
* Install and free a interrupt handler.
*/
void pic_irq_enable(unsigned int vec)
{
if ((vec >= 0) && (vec < 32))
mtdcr(UIC0ER, mfdcr(UIC0ER) | UIC_MASK(vec));
else if ((vec >= 32) && (vec < 64))
mtdcr(UIC1ER, mfdcr(UIC1ER) | UIC_MASK(vec));
else if ((vec >= 64) && (vec < 96))
mtdcr(UIC2ER, mfdcr(UIC2ER) | UIC_MASK(vec));
else if (vec >= 96)
mtdcr(UIC3ER, mfdcr(UIC3ER) | UIC_MASK(vec));
debug("Install interrupt vector %d\n", vec);
}
void pic_irq_disable(unsigned int vec)
{
if ((vec >= 0) && (vec < 32))
mtdcr(UIC0ER, mfdcr(UIC0ER) & ~UIC_MASK(vec));
else if ((vec >= 32) && (vec < 64))
mtdcr(UIC1ER, mfdcr(UIC1ER) & ~UIC_MASK(vec));
else if ((vec >= 64) && (vec < 96))
mtdcr(UIC2ER, mfdcr(UIC2ER) & ~UIC_MASK(vec));
else if (vec >= 96)
mtdcr(UIC3ER, mfdcr(UIC3ER) & ~UIC_MASK(vec));
}

View File

@ -1,45 +0,0 @@
/*
* (C) Copyright 2007
* Markus Klotzbuecher, DENX Software Engineering <mk@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT)
#ifdef CONFIG_4xx_DCACHE
#include <asm/mmu.h>
DECLARE_GLOBAL_DATA_PTR;
#endif
int usb_cpu_init(void)
{
#ifdef CONFIG_4xx_DCACHE
/* disable cache */
change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, TLB_WORD2_I_ENABLE);
#endif
return 0;
}
int usb_cpu_stop(void)
{
#ifdef CONFIG_4xx_DCACHE
/* enable cache */
change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, 0);
#endif
return 0;
}
int usb_cpu_init_fail(void)
{
#ifdef CONFIG_4xx_DCACHE
/* enable cache */
change_tlb(gd->bd->bi_memstart, gd->bd->bi_memsize, 0);
#endif
return 0;
}
#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT) */

File diff suppressed because it is too large Load Diff

View File

@ -1,405 +0,0 @@
/*
* URB OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
*
* usb-ohci.h
*/
static int cc_to_error[16] = {
/* mapping of the OHCI CC status to error codes */
/* No Error */ 0,
/* CRC Error */ USB_ST_CRC_ERR,
/* Bit Stuff */ USB_ST_BIT_ERR,
/* Data Togg */ USB_ST_CRC_ERR,
/* Stall */ USB_ST_STALLED,
/* DevNotResp */ -1,
/* PIDCheck */ USB_ST_BIT_ERR,
/* UnExpPID */ USB_ST_BIT_ERR,
/* DataOver */ USB_ST_BUF_ERR,
/* DataUnder */ USB_ST_BUF_ERR,
/* reservd */ -1,
/* reservd */ -1,
/* BufferOver */ USB_ST_BUF_ERR,
/* BuffUnder */ USB_ST_BUF_ERR,
/* Not Access */ -1,
/* Not Access */ -1
};
/* ED States */
#define ED_NEW 0x00
#define ED_UNLINK 0x01
#define ED_OPER 0x02
#define ED_DEL 0x04
#define ED_URB_DEL 0x08
/* usb_ohci_ed */
struct ed {
__u32 hwINFO;
__u32 hwTailP;
__u32 hwHeadP;
__u32 hwNextED;
struct ed *ed_prev;
__u8 int_period;
__u8 int_branch;
__u8 int_load;
__u8 int_interval;
__u8 state;
__u8 type;
__u16 last_iso;
struct ed *ed_rm_list;
struct usb_device *usb_dev;
__u32 unused[3];
} __attribute__((aligned(16)));
typedef struct ed ed_t;
/* TD info field */
#define TD_CC 0xf0000000
#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
#define TD_EC 0x0C000000
#define TD_T 0x03000000
#define TD_T_DATA0 0x02000000
#define TD_T_DATA1 0x03000000
#define TD_T_TOGGLE 0x00000000
#define TD_R 0x00040000
#define TD_DI 0x00E00000
#define TD_DI_SET(X) (((X) & 0x07)<< 21)
#define TD_DP 0x00180000
#define TD_DP_SETUP 0x00000000
#define TD_DP_IN 0x00100000
#define TD_DP_OUT 0x00080000
#define TD_ISO 0x00010000
#define TD_DEL 0x00020000
/* CC Codes */
#define TD_CC_NOERROR 0x00
#define TD_CC_CRC 0x01
#define TD_CC_BITSTUFFING 0x02
#define TD_CC_DATATOGGLEM 0x03
#define TD_CC_STALL 0x04
#define TD_DEVNOTRESP 0x05
#define TD_PIDCHECKFAIL 0x06
#define TD_UNEXPECTEDPID 0x07
#define TD_DATAOVERRUN 0x08
#define TD_DATAUNDERRUN 0x09
#define TD_BUFFEROVERRUN 0x0C
#define TD_BUFFERUNDERRUN 0x0D
#define TD_NOTACCESSED 0x0F
#define MAXPSW 1
struct td {
__u32 hwINFO;
__u32 hwCBP; /* Current Buffer Pointer */
__u32 hwNextTD; /* Next TD Pointer */
__u32 hwBE; /* Memory Buffer End Pointer */
__u16 hwPSW[MAXPSW];
__u8 unused;
__u8 index;
struct ed *ed;
struct td *next_dl_td;
struct usb_device *usb_dev;
int transfer_len;
__u32 data;
__u32 unused2[2];
} __attribute__((aligned(32)));
typedef struct td td_t;
#define OHCI_ED_SKIP (1 << 14)
/*
* The HCCA (Host Controller Communications Area) is a 256 byte
* structure defined in the OHCI spec. that the host controller is
* told the base address of. It must be 256-byte aligned.
*/
#define NUM_INTS 32 /* part of the OHCI standard */
struct ohci_hcca {
__u32 int_table[NUM_INTS]; /* Interrupt ED table */
__u16 frame_no; /* current frame number */
__u16 pad1; /* set to 0 on each frame_no change */
__u32 done_head; /* info returned for an interrupt */
u8 reserved_for_hc[116];
} __attribute__((aligned(256)));
/*
* Maximum number of root hub ports.
*/
#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */
/*
* This is the structure of the OHCI controller's memory mapped I/O
* region. This is Memory Mapped I/O. You must use the readl() and
* writel() macros defined in asm/io.h to access these!!
*/
struct ohci_regs {
/* control and status registers */
__u32 revision;
__u32 control;
__u32 cmdstatus;
__u32 intrstatus;
__u32 intrenable;
__u32 intrdisable;
/* memory pointers */
__u32 hcca;
__u32 ed_periodcurrent;
__u32 ed_controlhead;
__u32 ed_controlcurrent;
__u32 ed_bulkhead;
__u32 ed_bulkcurrent;
__u32 donehead;
/* frame counters */
__u32 fminterval;
__u32 fmremaining;
__u32 fmnumber;
__u32 periodicstart;
__u32 lsthresh;
/* Root hub ports */
struct ohci_roothub_regs {
__u32 a;
__u32 b;
__u32 status;
__u32 portstatus[MAX_ROOT_PORTS];
} roothub;
} __attribute__((aligned(32)));
/* OHCI CONTROL AND STATUS REGISTER MASKS */
/*
* HcControl (control) register masks
*/
#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
/* pre-shifted values for HCFS */
# define OHCI_USB_RESET (0 << 6)
# define OHCI_USB_RESUME (1 << 6)
# define OHCI_USB_OPER (2 << 6)
# define OHCI_USB_SUSPEND (3 << 6)
/*
* HcCommandStatus (cmdstatus) register masks
*/
#define OHCI_HCR (1 << 0) /* host controller reset */
#define OHCI_CLF (1 << 1) /* control list filled */
#define OHCI_BLF (1 << 2) /* bulk list filled */
#define OHCI_OCR (1 << 3) /* ownership change request */
#define OHCI_SOC (3 << 16) /* scheduling overrun count */
/*
* masks used with interrupt registers:
* HcInterruptStatus (intrstatus)
* HcInterruptEnable (intrenable)
* HcInterruptDisable (intrdisable)
*/
#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
#define OHCI_INTR_SF (1 << 2) /* start frame */
#define OHCI_INTR_RD (1 << 3) /* resume detect */
#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
#define OHCI_INTR_OC (1 << 30) /* ownership change */
#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
/* Virtual Root HUB */
struct virt_root_hub {
int devnum; /* Address of Root Hub endpoint */
void *dev; /* was urb */
void *int_addr;
int send;
int interval;
};
/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
/* destination of request */
#define RH_INTERFACE 0x01
#define RH_ENDPOINT 0x02
#define RH_OTHER 0x03
#define RH_CLASS 0x20
#define RH_VENDOR 0x40
/* Requests: bRequest << 8 | bmRequestType */
#define RH_GET_STATUS 0x0080
#define RH_CLEAR_FEATURE 0x0100
#define RH_SET_FEATURE 0x0300
#define RH_SET_ADDRESS 0x0500
#define RH_GET_DESCRIPTOR 0x0680
#define RH_SET_DESCRIPTOR 0x0700
#define RH_GET_CONFIGURATION 0x0880
#define RH_SET_CONFIGURATION 0x0900
#define RH_GET_STATE 0x0280
#define RH_GET_INTERFACE 0x0A80
#define RH_SET_INTERFACE 0x0B00
#define RH_SYNC_FRAME 0x0C80
/* Our Vendor Specific Request */
#define RH_SET_EP 0x2000
/* Hub port features */
#define RH_PORT_CONNECTION 0x00
#define RH_PORT_ENABLE 0x01
#define RH_PORT_SUSPEND 0x02
#define RH_PORT_OVER_CURRENT 0x03
#define RH_PORT_RESET 0x04
#define RH_PORT_POWER 0x08
#define RH_PORT_LOW_SPEED 0x09
#define RH_C_PORT_CONNECTION 0x10
#define RH_C_PORT_ENABLE 0x11
#define RH_C_PORT_SUSPEND 0x12
#define RH_C_PORT_OVER_CURRENT 0x13
#define RH_C_PORT_RESET 0x14
/* Hub features */
#define RH_C_HUB_LOCAL_POWER 0x00
#define RH_C_HUB_OVER_CURRENT 0x01
#define RH_DEVICE_REMOTE_WAKEUP 0x00
#define RH_ENDPOINT_STALL 0x01
#define RH_ACK 0x01
#define RH_REQ_ERR -1
#define RH_NACK 0x00
/* OHCI ROOT HUB REGISTER MASKS */
/* roothub.portstatus [i] bits */
#define RH_PS_CCS 0x00000001 /* current connect status */
#define RH_PS_PES 0x00000002 /* port enable status */
#define RH_PS_PSS 0x00000004 /* port suspend status */
#define RH_PS_POCI 0x00000008 /* port over current indicator */
#define RH_PS_PRS 0x00000010 /* port reset status */
#define RH_PS_PPS 0x00000100 /* port power status */
#define RH_PS_LSDA 0x00000200 /* low speed device attached */
#define RH_PS_CSC 0x00010000 /* connect status change */
#define RH_PS_PESC 0x00020000 /* port enable status change */
#define RH_PS_PSSC 0x00040000 /* port suspend status change */
#define RH_PS_OCIC 0x00080000 /* over current indicator change */
#define RH_PS_PRSC 0x00100000 /* port reset status change */
/* roothub.status bits */
#define RH_HS_LPS 0x00000001 /* local power status */
#define RH_HS_OCI 0x00000002 /* over current indicator */
#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
#define RH_HS_LPSC 0x00010000 /* local power status change */
#define RH_HS_OCIC 0x00020000 /* over current indicator change */
#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
/* roothub.b masks */
#define RH_B_DR 0x0000ffff /* device removable flags */
#define RH_B_PPCM 0xffff0000 /* port power control mask */
/* roothub.a masks */
#define RH_A_NDP (0xff << 0) /* number of downstream ports */
#define RH_A_PSM (1 << 8) /* power switching mode */
#define RH_A_NPS (1 << 9) /* no power switching */
#define RH_A_DT (1 << 10) /* device type (mbz) */
#define RH_A_OCPM (1 << 11) /* over current protection mode */
#define RH_A_NOCP (1 << 12) /* no over current protection */
#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
/* urb */
#define N_URB_TD 48
typedef struct {
ed_t *ed;
__u16 length; /* number of tds associated with this request */
__u16 td_cnt; /* number of tds already serviced */
int state;
unsigned long pipe;
int actual_length;
td_t *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */
} urb_priv_t;
#define URB_DEL 1
/*
* This is the full ohci controller description
*
* Note how the "proper" USB information is just
* a subset of what the full implementation needs. (Linus)
*/
typedef struct ohci {
struct ohci_hcca *hcca; /* hcca */
/*dma_addr_t hcca_dma; */
int irq;
int disabled; /* e.g. got a UE, we're hung */
int sleeping;
unsigned long flags; /* for HC bugs */
struct ohci_regs *regs; /* OHCI controller's memory */
ed_t *ed_rm_list[2]; /* lists of all endpoints to be removed */
ed_t *ed_bulktail; /* last endpoint of bulk list */
ed_t *ed_controltail; /* last endpoint of control list */
int intrstatus;
__u32 hc_control; /* copy of the hc control reg */
struct usb_device *dev[32];
struct virt_root_hub rh;
const char *slot_name;
} ohci_t;
#define NUM_EDS 8 /* num of preallocated endpoint descriptors */
struct ohci_device {
ed_t ed[NUM_EDS];
int ed_cnt;
};
/* hcd */
/* endpoint */
static int ep_link(ohci_t * ohci, ed_t * ed);
static int ep_unlink(ohci_t * ohci, ed_t * ed);
static ed_t *ep_add_ed(struct usb_device *usb_dev, unsigned long pipe);
/*-------------------------------------------------------------------------*/
/* we need more TDs than EDs */
#define NUM_TD 64
/* +1 so we can align the storage */
td_t gtd[NUM_TD + 1];
/* pointers to aligned storage */
td_t *ptd;
/* TDs ... */
static inline struct td *td_alloc(struct usb_device *usb_dev)
{
int i;
struct td *td;
td = NULL;
for (i = 0; i < NUM_TD; i++) {
if (ptd[i].usb_dev == NULL) {
td = &ptd[i];
td->usb_dev = usb_dev;
break;
}
}
return td;
}
static inline void ed_free(struct ed *ed)
{
ed->usb_dev = NULL;
}

View File

@ -1,88 +0,0 @@
/*
* (C) Copyright 2008
* Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@gmail.com
* This work has been supported by: QTechnology http://qtec.com/
* Based on interrupts.c Wolfgang Denk-DENX Software Engineering-wd@denx.de
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <asm/processor.h>
#include <asm/interrupt.h>
#include <asm/ppc4xx.h>
#include <ppc_asm.tmpl>
#include <asm/io.h>
#include <asm/xilinx_irq.h>
DECLARE_GLOBAL_DATA_PTR;
void pic_enable(void)
{
debug("Xilinx PIC at 0x%8x\n", intc);
/*
* Disable all external interrupts until they are
* explicitly requested.
*/
out_be32((u32 *) IER, 0);
/* Acknowledge any pending interrupts just in case. */
out_be32((u32 *) IAR, 0xffffffff);
/* Turn on the Master Enable. */
out_be32((u32 *) MER, 0x3UL);
return;
}
int xilinx_pic_irq_get(void)
{
u32 irq;
irq = in_be32((u32 *) IVR);
/* If no interrupt is pending then all bits of the IVR are set to 1. As
* the IVR is as many bits wide as numbers of inputs are available.
* Therefore, if all bits of the IVR are set to one, its content will
* be bigger than XPAR_INTC_MAX_NUM_INTR_INPUTS.
*/
if (irq >= XPAR_INTC_MAX_NUM_INTR_INPUTS)
irq = -1; /* report no pending interrupt. */
debug("get_irq: %d\n", irq);
return (irq);
}
void pic_irq_enable(unsigned int irq)
{
u32 mask = IRQ_MASK(irq);
debug("enable: %d\n", irq);
out_be32((u32 *) SIE, mask);
}
void pic_irq_disable(unsigned int irq)
{
u32 mask = IRQ_MASK(irq);
debug("disable: %d\n", irq);
out_be32((u32 *) CIE, mask);
}
void pic_irq_ack(unsigned int irq)
{
u32 mask = IRQ_MASK(irq);
debug("ack: %d\n", irq);
out_be32((u32 *) IAR, mask);
}
void external_interrupt(struct pt_regs *regs)
{
int irq;
irq = xilinx_pic_irq_get();
if (irq < 0)
return;
interrupt_run_handler(irq);
return;
}