The following MPC5121e subsystems are supported: - low-level CPU init - NOR Boot Flash (common CFI driver) - DDR SDRAM - FEC - I2C - Watchdog Signed-off-by: Grzegorz Bernacki <gjb@semihalf.com> Signed-off-by: Rafal Jaworowski <raj@semihalf.com> Signed-off-by: Jan Wrobel <wrr@semihalf.com>master
parent
1863cfb7b1
commit
8993e54b6f
@ -0,0 +1,50 @@ |
||||
#
|
||||
# (C) Copyright 2007
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk |
||||
|
||||
LIB = $(obj)lib$(BOARD).a
|
||||
|
||||
COBJS := $(BOARD).o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS) |
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
||||
clean: |
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean |
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk |
||||
|
||||
sinclude $(obj).depend |
||||
|
||||
#########################################################################
|
@ -0,0 +1,188 @@ |
||||
/*
|
||||
* (C) Copyright 2007 DENX Software Engineering |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <mpc512x.h> |
||||
#include <asm/bitops.h> |
||||
#include <command.h> |
||||
|
||||
/* Clocks in use */ |
||||
#define SCCR1_CLOCKS_EN (CLOCK_SCCR1_CFG_EN | \ |
||||
CLOCK_SCCR1_LPC_EN | \
|
||||
CLOCK_SCCR1_PSC_EN(CONFIG_PSC_CONSOLE) | \
|
||||
CLOCK_SCCR1_PSCFIFO_EN | \
|
||||
CLOCK_SCCR1_DDR_EN | \
|
||||
CLOCK_SCCR1_FEC_EN) |
||||
|
||||
#define SCCR2_CLOCKS_EN (CLOCK_SCCR2_MEM_EN | \ |
||||
CLOCK_SCCR2_SPDIF_EN | \
|
||||
CLOCK_SCCR2_I2C_EN) |
||||
|
||||
#define CSAW_START(start) ((start) & 0xFFFF0000) |
||||
#define CSAW_STOP(start, size) (((start) + (size) - 1) >> 16) |
||||
|
||||
long int fixed_sdram(void); |
||||
|
||||
int board_early_init_f (void) |
||||
{ |
||||
volatile immap_t *im = (immap_t *) CFG_IMMR; |
||||
u32 lpcaw; |
||||
|
||||
/*
|
||||
* Initialize Local Window for the CPLD registers access (CS2 selects |
||||
* the CPLD chip) |
||||
*/ |
||||
im->sysconf.lpcs2aw = CSAW_START(CFG_CPLD_BASE) | |
||||
CSAW_STOP(CFG_CPLD_BASE, CFG_CPLD_SIZE); |
||||
im->lpc.cs_cfg[2] = CFG_CS2_CFG; |
||||
|
||||
/*
|
||||
* According to MPC5121e RM, configuring local access windows should |
||||
* be followed by a dummy read of the config register that was |
||||
* modified last and an isync |
||||
*/ |
||||
lpcaw = im->sysconf.lpcs2aw; |
||||
__asm__ __volatile__ ("isync"); |
||||
|
||||
/*
|
||||
* Disable Boot NOR FLASH write protect - CPLD Reg 8 NOR FLASH Control |
||||
* |
||||
* Without this the flash identification routine fails, as it needs to issue |
||||
* write commands in order to establish the device ID. |
||||
*/ |
||||
*((volatile u8 *)(CFG_CPLD_BASE + 0x08)) = 0xC1; |
||||
|
||||
/*
|
||||
* Enable clocks |
||||
*/ |
||||
im->clk.sccr[0] = SCCR1_CLOCKS_EN; |
||||
im->clk.sccr[1] = SCCR2_CLOCKS_EN; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
long int initdram (int board_type) |
||||
{ |
||||
u32 msize = 0; |
||||
|
||||
puts ("Initializing\n"); |
||||
msize = fixed_sdram (); |
||||
puts (" DDR RAM: "); |
||||
|
||||
return msize; |
||||
} |
||||
|
||||
/*
|
||||
* fixed sdram init -- the board doesn't use memory modules that have serial presence |
||||
* detect or similar mechanism for discovery of the DRAM settings |
||||
*/ |
||||
long int fixed_sdram (void) |
||||
{ |
||||
volatile immap_t *im = (immap_t *) CFG_IMMR; |
||||
u32 msize = CFG_DDR_SIZE * 1024 * 1024; |
||||
u32 msize_log2 = __ilog2 (msize); |
||||
u32 i; |
||||
|
||||
/* Initialize IO Control */ |
||||
im->io_ctrl.regs[MEM_IDX] = IOCTRL_MUX_DDR; |
||||
|
||||
/* Initialize DDR Local Window */ |
||||
im->sysconf.ddrlaw.bar = CFG_DDR_BASE & 0xFFFFF000; |
||||
im->sysconf.ddrlaw.ar = msize_log2 - 1; |
||||
|
||||
/*
|
||||
* According to MPC5121e RM, configuring local access windows should |
||||
* be followed by a dummy read of the config register that was |
||||
* modified last and an isync |
||||
*/ |
||||
i = im->sysconf.ddrlaw.ar; |
||||
__asm__ __volatile__ ("isync"); |
||||
|
||||
/* Enable DDR */ |
||||
im->mddrc.ddr_sys_config = CFG_MDDRC_SYS_CFG_EN; |
||||
|
||||
/* Initialize DDR Priority Manager */ |
||||
im->mddrc.prioman_config1 = CFG_MDDRCGRP_PM_CFG1; |
||||
im->mddrc.prioman_config2 = CFG_MDDRCGRP_PM_CFG2; |
||||
im->mddrc.hiprio_config = CFG_MDDRCGRP_HIPRIO_CFG; |
||||
im->mddrc.lut_table0_main_upper = CFG_MDDRCGRP_LUT0_MU; |
||||
im->mddrc.lut_table1_main_upper = CFG_MDDRCGRP_LUT1_MU; |
||||
im->mddrc.lut_table2_main_upper = CFG_MDDRCGRP_LUT2_MU; |
||||
im->mddrc.lut_table3_main_upper = CFG_MDDRCGRP_LUT3_MU; |
||||
im->mddrc.lut_table4_main_upper = CFG_MDDRCGRP_LUT4_MU; |
||||
im->mddrc.lut_table0_main_lower = CFG_MDDRCGRP_LUT0_ML; |
||||
im->mddrc.lut_table1_main_lower = CFG_MDDRCGRP_LUT1_ML; |
||||
im->mddrc.lut_table2_main_lower = CFG_MDDRCGRP_LUT2_ML; |
||||
im->mddrc.lut_table3_main_lower = CFG_MDDRCGRP_LUT3_ML; |
||||
im->mddrc.lut_table4_main_lower = CFG_MDDRCGRP_LUT4_ML; |
||||
im->mddrc.lut_table0_alternate_upper = CFG_MDDRCGRP_LUT0_AU; |
||||
im->mddrc.lut_table1_alternate_upper = CFG_MDDRCGRP_LUT1_AU; |
||||
im->mddrc.lut_table2_alternate_upper = CFG_MDDRCGRP_LUT2_AU; |
||||
im->mddrc.lut_table3_alternate_upper = CFG_MDDRCGRP_LUT3_AU; |
||||
im->mddrc.lut_table4_alternate_upper = CFG_MDDRCGRP_LUT4_AU; |
||||
im->mddrc.lut_table0_alternate_lower = CFG_MDDRCGRP_LUT0_AU; |
||||
im->mddrc.lut_table1_alternate_lower = CFG_MDDRCGRP_LUT1_AL; |
||||
im->mddrc.lut_table2_alternate_lower = CFG_MDDRCGRP_LUT2_AL; |
||||
im->mddrc.lut_table3_alternate_lower = CFG_MDDRCGRP_LUT3_AL; |
||||
im->mddrc.lut_table4_alternate_lower = CFG_MDDRCGRP_LUT4_AL; |
||||
|
||||
/* Initialize MDDRC */ |
||||
im->mddrc.ddr_sys_config = CFG_MDDRC_SYS_CFG; |
||||
im->mddrc.ddr_time_config0 = CFG_MDDRC_TIME_CFG0; |
||||
im->mddrc.ddr_time_config1 = CFG_MDDRC_TIME_CFG1; |
||||
im->mddrc.ddr_time_config2 = CFG_MDDRC_TIME_CFG2; |
||||
|
||||
/* Initialize DDR */ |
||||
for (i = 0; i < 10; i++) |
||||
im->mddrc.ddr_command = CFG_MICRON_NOP; |
||||
|
||||
im->mddrc.ddr_command = CFG_MICRON_PCHG_ALL; |
||||
im->mddrc.ddr_command = CFG_MICRON_EM2; |
||||
im->mddrc.ddr_command = CFG_MICRON_EM3; |
||||
im->mddrc.ddr_command = CFG_MICRON_EN_DLL; |
||||
im->mddrc.ddr_command = CFG_MICRON_RST_DLL; |
||||
im->mddrc.ddr_command = CFG_MICRON_PCHG_ALL; |
||||
im->mddrc.ddr_command = CFG_MICRON_RFSH; |
||||
im->mddrc.ddr_command = CFG_MICRON_INIT_DEV_OP; |
||||
im->mddrc.ddr_command = CFG_MICRON_OCD_DEFAULT; |
||||
im->mddrc.ddr_command = CFG_MICRON_OCD_EXIT; |
||||
|
||||
for (i = 0; i < 10; i++) |
||||
im->mddrc.ddr_command = CFG_MICRON_NOP; |
||||
|
||||
/* Start MDDRC */ |
||||
im->mddrc.ddr_time_config0 = CFG_MDDRC_TIME_CFG0_RUN; |
||||
im->mddrc.ddr_sys_config = CFG_MDDRC_SYS_CFG_RUN; |
||||
|
||||
return msize; |
||||
} |
||||
|
||||
int checkboard (void) |
||||
{ |
||||
ushort brd_rev = *(vu_short *) (CFG_CPLD_BASE + 0x00); |
||||
uchar cpld_rev = *(vu_char *) (CFG_CPLD_BASE + 0x02); |
||||
|
||||
printf ("Board: ADS5121 rev. 0x%04x (CPLD rev. 0x%02x)\n", |
||||
brd_rev, cpld_rev); |
||||
return 0; |
||||
} |
@ -0,0 +1,23 @@ |
||||
#
|
||||
# (C) Copyright 2007 DENX Software Engineering
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
TEXT_BASE = 0xFFF00000
|
@ -0,0 +1,122 @@ |
||||
/* |
||||
* (C) Copyright 2007 DENX Software Engineering. |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
OUTPUT_ARCH(powerpc) |
||||
SECTIONS |
||||
{ |
||||
/* Read-only sections, merged into text segment: */ |
||||
. = + SIZEOF_HEADERS; |
||||
.interp : { *(.interp) } |
||||
.hash : { *(.hash) } |
||||
.dynsym : { *(.dynsym) } |
||||
.dynstr : { *(.dynstr) } |
||||
.rel.text : { *(.rel.text) } |
||||
.rela.text : { *(.rela.text) } |
||||
.rel.data : { *(.rel.data) } |
||||
.rela.data : { *(.rela.data) } |
||||
.rel.rodata : { *(.rel.rodata) } |
||||
.rela.rodata : { *(.rela.rodata) } |
||||
.rel.got : { *(.rel.got) } |
||||
.rela.got : { *(.rela.got) } |
||||
.rel.ctors : { *(.rel.ctors) } |
||||
.rela.ctors : { *(.rela.ctors) } |
||||
.rel.dtors : { *(.rel.dtors) } |
||||
.rela.dtors : { *(.rela.dtors) } |
||||
.rel.bss : { *(.rel.bss) } |
||||
.rela.bss : { *(.rela.bss) } |
||||
.rel.plt : { *(.rel.plt) } |
||||
.rela.plt : { *(.rela.plt) } |
||||
.init : { *(.init) } |
||||
.plt : { *(.plt) } |
||||
.text : |
||||
{ |
||||
cpu/mpc512x/start.o (.text) |
||||
*(.text) |
||||
*(.fixup) |
||||
*(.got1) |
||||
. = ALIGN(16); |
||||
*(.rodata) |
||||
*(.rodata1) |
||||
*(.rodata.str1.4) |
||||
*(.eh_frame) |
||||
} |
||||
.fini : { *(.fini) } =0 |
||||
.ctors : { *(.ctors) } |
||||
.dtors : { *(.dtors) } |
||||
|
||||
/* Read-write section, merged into data segment: */ |
||||
. = (. + 0x0FFF) & 0xFFFFF000; |
||||
_erotext = .; |
||||
PROVIDE (erotext = .); |
||||
.reloc : |
||||
{ |
||||
*(.got) |
||||
_GOT2_TABLE_ = .; |
||||
*(.got2) |
||||
_FIXUP_TABLE_ = .; |
||||
*(.fixup) |
||||
} |
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; |
||||
__fixup_entries = (. - _FIXUP_TABLE_) >> 2; |
||||
|
||||
.data : |
||||
{ |
||||
*(.data) |
||||
*(.data1) |
||||
*(.sdata) |
||||
*(.sdata2) |
||||
*(.dynamic) |
||||
CONSTRUCTORS |
||||
} |
||||
_edata = .; |
||||
PROVIDE (edata = .); |
||||
|
||||
. = .; |
||||
__u_boot_cmd_start = .; |
||||
.u_boot_cmd : { *(.u_boot_cmd) } |
||||
__u_boot_cmd_end = .; |
||||
|
||||
|
||||
. = .; |
||||
__start___ex_table = .; |
||||
__ex_table : { *(__ex_table) } |
||||
__stop___ex_table = .; |
||||
|
||||
. = ALIGN(4096); |
||||
__init_begin = .; |
||||
.text.init : { *(.text.init) } |
||||
.data.init : { *(.data.init) } |
||||
. = ALIGN(4096); |
||||
__init_end = .; |
||||
|
||||
__bss_start = .; |
||||
.bss : |
||||
{ |
||||
*(.sbss) *(.scommon) |
||||
*(.dynbss) |
||||
*(.bss) |
||||
*(COMMON) |
||||
} |
||||
_end = . ; |
||||
PROVIDE (end = .); |
||||
} |
||||
ENTRY(_start) |
@ -0,0 +1,46 @@ |
||||
#
|
||||
# (C) Copyright 2007 DENX Software Engineering
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk |
||||
|
||||
LIB = $(obj)lib$(CPU).a
|
||||
|
||||
START = start.o
|
||||
COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o fec.o i2c.o
|
||||
|
||||
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
|
||||
START := $(addprefix $(obj),$(START))
|
||||
|
||||
all: $(obj).depend $(START) $(LIB) |
||||
|
||||
$(LIB): $(OBJS) |
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk |
||||
|
||||
sinclude $(obj).depend |
||||
|
||||
#########################################################################
|
@ -0,0 +1,25 @@ |
||||
#
|
||||
# (C) Copyright 2007 DENX Software Engineering
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
|
||||
|
||||
PLATFORM_CPPFLAGS += -DCONFIG_MPC512X -DCONFIG_E300 \
|
||||
-ffixed-r2 -ffixed-r29 -msoft-float -mcpu=603e
|
@ -0,0 +1,127 @@ |
||||
/*
|
||||
* Copyright (C) 2004-2006 Freescale Semiconductor, Inc. |
||||
* (C) Copyright 2007 DENX Software Engineering |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
/*
|
||||
* CPU specific code for the MPC512x family. |
||||
* |
||||
* Derived from the MPC83xx code. |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <mpc512x.h> |
||||
#include <asm/processor.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
int checkcpu (void) |
||||
{ |
||||
volatile immap_t *immr = (immap_t *) CFG_IMMR; |
||||
ulong clock = gd->cpu_clk; |
||||
u32 pvr = get_pvr (); |
||||
u32 spridr = immr->sysconf.spridr; |
||||
char buf[32]; |
||||
|
||||
puts("CPU: "); |
||||
|
||||
switch (spridr & 0xffff0000) { |
||||
case SPR_5121E: |
||||
puts ("MPC5121e "); |
||||
break; |
||||
default: |
||||
printf ("Unknown part ID %08x ", spridr & 0xffff0000); |
||||
} |
||||
printf ("rev. %d.%d, Core ", SVR_MJREV (spridr), SVR_MNREV (spridr)); |
||||
|
||||
switch (pvr & 0xffff0000) { |
||||
case PVR_E300C4: |
||||
puts ("e300c4 "); |
||||
break; |
||||
default: |
||||
puts ("unknown "); |
||||
} |
||||
printf ("at %s MHz, CSB at %3d MHz\n", strmhz(buf, clock), |
||||
gd->csb_clk / 1000000); |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
int |
||||
do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
||||
{ |
||||
ulong msr; |
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR; |
||||
|
||||
/* Interrupts and MMU off */ |
||||
__asm__ __volatile__ ("mfmsr %0":"=r" (msr):); |
||||
|
||||
msr &= ~( MSR_EE | MSR_IR | MSR_DR); |
||||
__asm__ __volatile__ ("mtmsr %0"::"r" (msr)); |
||||
|
||||
/*
|
||||
* Enable Reset Control Reg - "RSTE" is the magic word that let us go |
||||
*/ |
||||
immap->reset.rpr = 0x52535445; |
||||
|
||||
/* Verify Reset Control Reg is enabled */ |
||||
while (!((immap->reset.rcer) & RCER_CRE)) |
||||
; |
||||
|
||||
printf ("Resetting the board.\n"); |
||||
udelay(200); |
||||
|
||||
/* Perform reset */ |
||||
immap->reset.rcr = RCR_SWHR; |
||||
|
||||
/* Unreached... */ |
||||
return 1; |
||||
} |
||||
|
||||
|
||||
/*
|
||||
* Get timebase clock frequency (like cpu_clk in Hz) |
||||
*/ |
||||
unsigned long get_tbclk (void) |
||||
{ |
||||
ulong tbclk; |
||||
|
||||
tbclk = (gd->bus_clk + 3L) / 4L; |
||||
|
||||
return tbclk; |
||||
} |
||||
|
||||
|
||||
#if defined(CONFIG_WATCHDOG) |
||||
void watchdog_reset (void) |
||||
{ |
||||
int re_enable = disable_interrupts (); |
||||
|
||||
/* Reset watchdog */ |
||||
volatile immap_t *immr = (immap_t *) CFG_IMMR; |
||||
immr->wdt.swsrr = 0x556c; |
||||
immr->wdt.swsrr = 0xaa39; |
||||
|
||||
if (re_enable) |
||||
enable_interrupts (); |
||||
} |
||||
#endif |
@ -0,0 +1,87 @@ |
||||
/*
|
||||
* Copyright (C) 2004-2006 Freescale Semiconductor, Inc. |
||||
* (C) Copyright 2007 DENX Software Engineering |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
* Derived from the MPC83xx code. |
||||
* |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <mpc512x.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
/*
|
||||
* Set up the memory map, initialize registers, |
||||
*/ |
||||
void cpu_init_f (volatile immap_t * im) |
||||
{ |
||||
u32 ips_div; |
||||
|
||||
/* Pointer is writable since we allocated a register for it */ |
||||
gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET); |
||||
|
||||
/* Clear initial global data */ |
||||
memset ((void *) gd, 0, sizeof (gd_t)); |
||||
|
||||
/* system performance tweaking */ |
||||
|
||||
#ifdef CFG_ACR_PIPE_DEP |
||||
/* Arbiter pipeline depth */ |
||||
im->arbiter.acr = (im->arbiter.acr & ~ACR_PIPE_DEP) | |
||||
(CFG_ACR_PIPE_DEP << ACR_PIPE_DEP_SHIFT); |
||||
#endif |
||||
|
||||
#ifdef CFG_ACR_RPTCNT |
||||
/* Arbiter repeat count */ |
||||
im->arbiter.acr = ((im->arbiter.acr & ~(ACR_RPTCNT)) | |
||||
(CFG_ACR_RPTCNT << ACR_RPTCNT_SHIFT)); |
||||
#endif |
||||
|
||||
/* RSR - Reset Status Register - clear all status */ |
||||
gd->reset_status = im->reset.rsr; |
||||
im->reset.rsr = ~(RSR_RES); |
||||
|
||||
/*
|
||||
* RMR - Reset Mode Register - enable checkstop reset |
||||
*/ |
||||
im->reset.rmr = (RMR_CSRE & (1 << RMR_CSRE_SHIFT)); |
||||
|
||||
/* Set IPS-CSB divider: IPS = 1/2 CSB */ |
||||
ips_div = im->clk.scfr[0]; |
||||
ips_div &= ~(SCFR1_IPS_DIV_MASK); |
||||
ips_div |= SCFR1_IPS_DIV << SCFR1_IPS_DIV_SHIFT; |
||||
im->clk.scfr[0] = ips_div; |
||||
|
||||
/*
|
||||
* Enable Time Base/Decrementer |
||||
* |
||||
* NOTICE: TB needs to be enabled as early as possible in order to |
||||
* have udelay() working; if not enabled, usually leads to a hang, like |
||||
* during FLASH chip identification etc.
|
||||
*/ |
||||
im->sysconf.spcr |= SPCR_TBEN; |
||||
} |
||||
|
||||
int cpu_init_r (void) |
||||
{ |
||||
return 0; |
||||
} |
@ -0,0 +1,801 @@ |
||||
/*
|
||||
* (C) Copyright 2003-2007 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* Derived from the MPC8xx FEC driver. |
||||
* Adapted for MPC512x by Grzegorz Bernacki <gjb@semihalf.com> |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <mpc512x.h> |
||||
#include <malloc.h> |
||||
#include <net.h> |
||||
#include <miiphy.h> |
||||
#include "fec.h" |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#define DEBUG 0 |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \ |
||||
defined(CONFIG_MPC512x_FEC) |
||||
|
||||
#if !(defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)) |
||||
#error "CONFIG_MII has to be defined!" |
||||
#endif |
||||
|
||||
#if (DEBUG & 0x40) |
||||
static uint32 local_crc32(char *string, unsigned int crc_value, int len); |
||||
#endif |
||||
|
||||
int fec512x_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal); |
||||
int fec512x_miiphy_write(char *devname, uint8 phyAddr, uint8 regAddr, uint16 data); |
||||
int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis); |
||||
|
||||
/********************************************************************/ |
||||
#if (DEBUG & 0x2) |
||||
static void mpc512x_fec_phydump (char *devname) |
||||
{ |
||||
uint16 phyStatus, i; |
||||
uint8 phyAddr = CONFIG_PHY_ADDR; |
||||
uint8 reg_mask[] = { |
||||
/* regs to print: 0...8, 21,27,31 */ |
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, |
||||
}; |
||||
|
||||
for (i = 0; i < 32; i++) { |
||||
if (reg_mask[i]) { |
||||
miiphy_read (devname, phyAddr, i, &phyStatus); |
||||
printf ("Mii reg %d: 0x%04x\n", i, phyStatus); |
||||
} |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
/********************************************************************/ |
||||
static int mpc512x_fec_bd_init (mpc512x_fec_priv *fec) |
||||
{ |
||||
int ix; |
||||
|
||||
/*
|
||||
* Receive BDs init |
||||
*/ |
||||
for (ix = 0; ix < FEC_RBD_NUM; ix++) { |
||||
fec->bdBase->rbd[ix].dataPointer = (uint32)&fec->bdBase->recv_frames[ix]; |
||||
fec->bdBase->rbd[ix].status = FEC_RBD_EMPTY; |
||||
fec->bdBase->rbd[ix].dataLength = 0; |
||||
} |
||||
|
||||
/*
|
||||
* have the last RBD to close the ring |
||||
*/ |
||||
fec->bdBase->rbd[ix - 1].status |= FEC_RBD_WRAP; |
||||
fec->rbdIndex = 0; |
||||
|
||||
/*
|
||||
* Trasmit BDs init |
||||
*/ |
||||
for (ix = 0; ix < FEC_TBD_NUM; ix++) { |
||||
fec->bdBase->tbd[ix].status = 0; |
||||
} |
||||
|
||||
/*
|
||||
* Have the last TBD to close the ring |
||||
*/ |
||||
fec->bdBase->tbd[ix - 1].status |= FEC_TBD_WRAP; |
||||
|
||||
/*
|
||||
* Initialize some indices |
||||
*/ |
||||
fec->tbdIndex = 0; |
||||
fec->usedTbdIndex = 0; |
||||
fec->cleanTbdNum = FEC_TBD_NUM; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
static void mpc512x_fec_rbd_clean (mpc512x_fec_priv *fec, volatile FEC_RBD * pRbd) |
||||
{ |
||||
/*
|
||||
* Reset buffer descriptor as empty |
||||
*/ |
||||
if ((fec->rbdIndex) == (FEC_RBD_NUM - 1)) |
||||
pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY); |
||||
else |
||||
pRbd->status = FEC_RBD_EMPTY; |
||||
|
||||
pRbd->dataLength = 0; |
||||
|
||||
/*
|
||||
* Increment BD count |
||||
*/ |
||||
fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM; |
||||
|
||||
/*
|
||||
* Now, we have an empty RxBD, notify FEC |
||||
*/ |
||||
fec->eth->r_des_active = 0x01000000; /* Descriptor polling active */ |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
static void mpc512x_fec_tbd_scrub (mpc512x_fec_priv *fec) |
||||
{ |
||||
volatile FEC_TBD *pUsedTbd; |
||||
|
||||
#if (DEBUG & 0x1) |
||||
printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n", |
||||
fec->cleanTbdNum, fec->usedTbdIndex); |
||||
#endif |
||||
|
||||
/*
|
||||
* process all the consumed TBDs |
||||
*/ |
||||
while (fec->cleanTbdNum < FEC_TBD_NUM) { |
||||
pUsedTbd = &fec->bdBase->tbd[fec->usedTbdIndex]; |
||||
if (pUsedTbd->status & FEC_TBD_READY) { |
||||
#if (DEBUG & 0x20) |
||||
printf ("Cannot clean TBD %d, in use\n", fec->usedTbdIndex); |
||||
#endif |
||||
return; |
||||
} |
||||
|
||||
/*
|
||||
* clean this buffer descriptor |
||||
*/ |
||||
if (fec->usedTbdIndex == (FEC_TBD_NUM - 1)) |
||||
pUsedTbd->status = FEC_TBD_WRAP; |
||||
else |
||||
pUsedTbd->status = 0; |
||||
|
||||
/*
|
||||
* update some indeces for a correct handling of the TBD ring |
||||
*/ |
||||
fec->cleanTbdNum++; |
||||
fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM; |
||||
} |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
static void mpc512x_fec_set_hwaddr (mpc512x_fec_priv *fec, char *mac) |
||||
{ |
||||
uint8 currByte; /* byte for which to compute the CRC */ |
||||
int byte; /* loop - counter */ |
||||
int bit; /* loop - counter */ |
||||
uint32 crc = 0xffffffff; /* initial value */ |
||||
|
||||
/*
|
||||
* The algorithm used is the following: |
||||
* we loop on each of the six bytes of the provided address, |
||||
* and we compute the CRC by left-shifting the previous |
||||
* value by one position, so that each bit in the current |
||||
* byte of the address may contribute the calculation. If |
||||
* the latter and the MSB in the CRC are different, then |
||||
* the CRC value so computed is also ex-ored with the |
||||
* "polynomium generator". The current byte of the address |
||||
* is also shifted right by one bit at each iteration. |
||||
* This is because the CRC generatore in hardware is implemented |
||||
* as a shift-register with as many ex-ores as the radixes |
||||
* in the polynomium. This suggests that we represent the |
||||
* polynomiumm itself as a 32-bit constant. |
||||
*/ |
||||
for (byte = 0; byte < 6; byte++) { |
||||
currByte = mac[byte]; |
||||
for (bit = 0; bit < 8; bit++) { |
||||
if ((currByte & 0x01) ^ (crc & 0x01)) { |
||||
crc >>= 1; |
||||
crc = crc ^ 0xedb88320; |
||||
} else { |
||||
crc >>= 1; |
||||
} |
||||
currByte >>= 1; |
||||
} |
||||
} |
||||
|
||||
crc = crc >> 26; |
||||
|
||||
/*
|
||||
* Set individual hash table register |
||||
*/ |
||||
if (crc >= 32) { |
||||
fec->eth->iaddr1 = (1 << (crc - 32)); |
||||
fec->eth->iaddr2 = 0; |
||||
} else { |
||||
fec->eth->iaddr1 = 0; |
||||
fec->eth->iaddr2 = (1 << crc); |
||||
} |
||||
|
||||
/*
|
||||
* Set physical address |
||||
*/ |
||||
fec->eth->paddr1 = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3]; |
||||
fec->eth->paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
static int mpc512x_fec_init (struct eth_device *dev, bd_t * bis) |
||||
{ |
||||
mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; |
||||
|
||||
#if (DEBUG & 0x1) |
||||
printf ("mpc512x_fec_init... Begin\n"); |
||||
#endif |
||||
|
||||
/* Set interrupt mask register */ |
||||
fec->eth->imask = 0x00000000; |
||||
|
||||
/* Clear FEC-Lite interrupt event register(IEVENT) */ |
||||
fec->eth->ievent = 0xffffffff; |
||||
|
||||
/* Set transmit fifo watermark register(X_WMRK), default = 64 */ |
||||
fec->eth->x_wmrk = 0x0; |
||||
|
||||
/* Set Opcode/Pause Duration Register */ |
||||
fec->eth->op_pause = 0x00010020; |
||||
|
||||
/* Frame length=1518; MII mode */ |
||||
fec->eth->r_cntrl = 0x05ee000c; |
||||
|
||||
/* Half-duplex, heartbeat disabled */ |
||||
fec->eth->x_cntrl = 0x00000000;
|
||||
|
||||
/* Enable MIB counters */ |
||||
fec->eth->mib_control = 0x0; |
||||
|
||||
/* Setup recv fifo start and buff size */ |
||||
fec->eth->r_fstart = 0x500; |
||||
fec->eth->r_buff_size = 0x5e0; |
||||
|
||||
/* Setup BD base addresses */ |
||||
fec->eth->r_des_start = (uint32)fec->bdBase->rbd; |
||||
fec->eth->x_des_start = (uint32)fec->bdBase->tbd; |
||||
|
||||
/* DMA Control */ |
||||
fec->eth->dma_control = 0xc0000000; |
||||
|
||||
/* Enable FEC */ |
||||
fec->eth->ecntrl |= 0x00000006; |
||||
|
||||
/* Initilize addresses and status words of BDs */ |
||||
mpc512x_fec_bd_init (fec); |
||||
|
||||
/* Descriptor polling active */
|
||||
fec->eth->r_des_active = 0x01000000; |
||||
|
||||
#if (DEBUG & 0x1) |
||||
printf("mpc512x_fec_init... Done \n"); |
||||
#endif |
||||
return 1; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
int mpc512x_fec_init_phy (struct eth_device *dev, bd_t * bis) |
||||
{ |
||||
mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; |
||||
const uint8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */ |
||||
int timeout = 1; |
||||
uint16 phyStatus; |
||||
|
||||
#if (DEBUG & 0x1) |
||||
printf ("mpc512x_fec_init_phy... Begin\n"); |
||||
#endif |
||||
|
||||
/*
|
||||
* Clear FEC-Lite interrupt event register(IEVENT) |
||||
*/ |
||||
fec->eth->ievent = 0xffffffff; |
||||
|
||||
/*
|
||||
* Set interrupt mask register |
||||
*/ |
||||
fec->eth->imask = 0x00000000; |
||||
|
||||
if (fec->xcv_type != SEVENWIRE) { |
||||
/*
|
||||
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock |
||||
* and do not drop the Preamble. |
||||
*/ |
||||
fec->eth->mii_speed = (((gd->ipb_clk / 1000000) / 5) + 1) << 1;
|
||||
|
||||
/*
|
||||
* Reset PHY, then delay 300ns |
||||
*/ |
||||
miiphy_write (dev->name, phyAddr, 0x0, 0x8000); |
||||
udelay (1000); |
||||
|
||||
if (fec->xcv_type == MII10) { |
||||
/*
|
||||
* Force 10Base-T, FDX operation |
||||
*/ |
||||
#if (DEBUG & 0x2) |
||||
printf ("Forcing 10 Mbps ethernet link... "); |
||||
#endif |
||||
miiphy_read (dev->name, phyAddr, 0x1, &phyStatus); |
||||
|
||||
miiphy_write (dev->name, phyAddr, 0x0, 0x0180); |
||||
|
||||
timeout = 20; |
||||
do { /* wait for link status to go down */ |
||||
udelay (10000); |
||||
if ((timeout--) == 0) { |
||||
#if (DEBUG & 0x2) |
||||
printf ("hmmm, should not have waited..."); |
||||
#endif |
||||
break; |
||||
} |
||||
miiphy_read (dev->name, phyAddr, 0x1, &phyStatus); |
||||
#if (DEBUG & 0x2) |
||||
printf ("="); |
||||
#endif |
||||
} while ((phyStatus & 0x0004)); /* !link up */ |
||||
|
||||
timeout = 1000; |
||||
do { /* wait for link status to come back up */ |
||||
udelay (10000); |
||||
if ((timeout--) == 0) { |
||||
printf ("failed. Link is down.\n"); |
||||
break; |
||||
} |
||||
miiphy_read (dev->name, phyAddr, 0x1, &phyStatus); |
||||
#if (DEBUG & 0x2) |
||||
printf ("+"); |
||||
#endif |
||||
} while (!(phyStatus & 0x0004)); /* !link up */ |
||||
|
||||
#if (DEBUG & 0x2) |
||||
printf ("done.\n"); |
||||
#endif |
||||
} else { /* MII100 */ |
||||
/*
|
||||
* Set the auto-negotiation advertisement register bits |
||||
*/ |
||||
miiphy_write (dev->name, phyAddr, 0x4, 0x01e1); |
||||
|
||||
/*
|
||||
* Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation |
||||
*/ |
||||
miiphy_write (dev->name, phyAddr, 0x0, 0x1200); |
||||
|
||||
/*
|
||||
* Wait for AN completion |
||||
*/ |
||||
timeout = 50000; |
||||
do { |
||||
udelay (1000); |
||||
|
||||
if ((timeout--) == 0) { |
||||
#if (DEBUG & 0x2) |
||||
printf ("PHY auto neg 0 failed...\n"); |
||||
#endif |
||||
return -1; |
||||
} |
||||
|
||||
if (miiphy_read (dev->name, phyAddr, 0x1, &phyStatus) != 0) { |
||||
#if (DEBUG & 0x2) |
||||
printf ("PHY auto neg 1 failed 0x%04x...\n", phyStatus); |
||||
#endif |
||||
return -1; |
||||
} |
||||
} while (!(phyStatus & 0x0004)); |
||||
|
||||
#if (DEBUG & 0x2) |
||||
printf ("PHY auto neg complete! \n"); |
||||
#endif |
||||
} |
||||
} |
||||
|
||||
#if (DEBUG & 0x2) |
||||
if (fec->xcv_type != SEVENWIRE) |
||||
mpc512x_fec_phydump (dev->name); |
||||
#endif |
||||
|
||||
#if (DEBUG & 0x1) |
||||
printf ("mpc512x_fec_init_phy... Done \n"); |
||||
#endif |
||||
return 1; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
static void mpc512x_fec_halt (struct eth_device *dev) |
||||
{ |
||||
mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; |
||||
int counter = 0xffff; |
||||
|
||||
#if (DEBUG & 0x2) |
||||
if (fec->xcv_type != SEVENWIRE) |
||||
mpc512x_fec_phydump (dev->name); |
||||
#endif |
||||
|
||||
/*
|
||||
* mask FEC chip interrupts |
||||
*/ |
||||
fec->eth->imask = 0; |
||||
|
||||
/*
|
||||
* issue graceful stop command to the FEC transmitter if necessary |
||||
*/ |
||||
fec->eth->x_cntrl |= 0x00000001; |
||||
|
||||
/*
|
||||
* wait for graceful stop to register |
||||
*/ |
||||
while ((counter--) && (!(fec->eth->ievent & 0x10000000))) ; |
||||
|
||||
/*
|
||||
* Disable the Ethernet Controller |
||||
*/ |
||||
fec->eth->ecntrl &= 0xfffffffd; |
||||
|
||||
/*
|
||||
* Issue a reset command to the FEC chip |
||||
*/ |
||||
fec->eth->ecntrl |= 0x1; |
||||
|
||||
/*
|
||||
* wait at least 16 clock cycles |
||||
*/ |
||||
udelay (10); |
||||
#if (DEBUG & 0x3) |
||||
printf ("Ethernet task stopped\n"); |
||||
#endif |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
|
||||
static int mpc512x_fec_send (struct eth_device *dev, volatile void *eth_data, |
||||
int data_length) |
||||
{ |
||||
/*
|
||||
* This routine transmits one frame. This routine only accepts |
||||
* 6-byte Ethernet addresses. |
||||
*/ |
||||
mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; |
||||
volatile FEC_TBD *pTbd; |
||||
|
||||
#if (DEBUG & 0x20) |
||||
printf("tbd status: 0x%04x\n", fec->tbdBase[fec->tbdIndex].status); |
||||
#endif |
||||
|
||||
/*
|
||||
* Clear Tx BD ring at first |
||||
*/ |
||||
mpc512x_fec_tbd_scrub (fec); |
||||
|
||||
/*
|
||||
* Check for valid length of data. |
||||
*/ |
||||
if ((data_length > 1500) || (data_length <= 0)) { |
||||
return -1; |
||||
} |
||||
|
||||
/*
|
||||
* Check the number of vacant TxBDs. |
||||
*/ |
||||
if (fec->cleanTbdNum < 1) { |
||||
#if (DEBUG & 0x20) |
||||
printf ("No available TxBDs ...\n"); |
||||
#endif |
||||
return -1; |
||||
} |
||||
|
||||
/*
|
||||
* Get the first TxBD to send the mac header |
||||
*/ |
||||
pTbd = &fec->bdBase->tbd[fec->tbdIndex]; |
||||
pTbd->dataLength = data_length; |
||||
pTbd->dataPointer = (uint32)eth_data; |
||||
pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY; |
||||
fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM; |
||||
|
||||
/* Activate transmit Buffer Descriptor polling */ |
||||
fec->eth->x_des_active = 0x01000000; /* Descriptor polling active */ |
||||
|
||||
#if (DEBUG & 0x8) |
||||
printf ( "+" ); |
||||
#endif |
||||
|
||||
fec->cleanTbdNum -= 1; |
||||
|
||||
/*
|
||||
* wait until frame is sent . |
||||
*/ |
||||
while (pTbd->status & FEC_TBD_READY) { |
||||
udelay (10); |
||||
#if (DEBUG & 0x8) |
||||
printf ("TDB status = %04x\n", pTbd->status); |
||||
#endif |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/********************************************************************/ |
||||
static int mpc512x_fec_recv (struct eth_device *dev) |
||||
{ |
||||
/*
|
||||
* This command pulls one frame from the card |
||||
*/ |
||||
mpc512x_fec_priv *fec = (mpc512x_fec_priv *)dev->priv; |
||||
volatile FEC_RBD *pRbd = &fec->bdBase->rbd[fec->rbdIndex]; |
||||
unsigned long ievent; |
||||
int frame_length, len = 0; |
||||
uchar buff[FEC_MAX_PKT_SIZE]; |
||||
|
||||
#if (DEBUG & 0x1) |
||||
printf ("mpc512x_fec_recv %d Start...\n", fec->rbdIndex); |
||||
#endif |
||||
#if (DEBUG & 0x8) |
||||
printf( "-" ); |
||||
#endif |
||||
|
||||
/*
|
||||
* Check if any critical events have happened |
||||
*/ |
||||
ievent = fec->eth->ievent; |
||||
fec->eth->ievent = ievent; |
||||
if (ievent & 0x20060000) { |
||||
/* BABT, Rx/Tx FIFO errors */ |
||||
mpc512x_fec_halt (dev); |
||||
mpc512x_fec_init (dev, NULL); |
||||
return 0; |
||||
} |
||||
if (ievent & 0x80000000) { |
||||
/* Heartbeat error */ |
||||
fec->eth->x_cntrl |= 0x00000001; |
||||
} |
||||
if (ievent & 0x10000000) { |
||||
/* Graceful stop complete */ |
||||
if (fec->eth->x_cntrl & 0x00000001) { |
||||
mpc512x_fec_halt (dev); |
||||
fec->eth->x_cntrl &= ~0x00000001; |
||||
mpc512x_fec_init (dev, NULL); |
||||
} |
||||
} |
||||
|
||||
if (!(pRbd->status & FEC_RBD_EMPTY)) { |
||||
if ((pRbd->status & FEC_RBD_LAST) &&
|
||||
!(pRbd->status & FEC_RBD_ERR) && |
||||
((pRbd->dataLength - 4) > 14)) { |
||||
|
||||
/*
|
||||
* Get buffer size |
||||
*/ |
||||
frame_length = pRbd->dataLength - 4; |
||||
|
||||
#if (DEBUG & 0x20) |
||||
{ |
||||
int i; |
||||
printf ("recv data hdr:"); |
||||
for (i = 0; i < 14; i++) |
||||
printf ("%x ", *((uint8*)pRbd->dataPointer + i)); |
||||
printf("\n"); |
||||
} |
||||
#endif |
||||
|
||||
/*
|
||||
* Fill the buffer and pass it to upper layers |
||||
*/ |
||||
memcpy (buff, (void*)pRbd->dataPointer, frame_length); |
||||
NetReceive ((uchar*)buff, frame_length); |
||||
len = frame_length; |
||||
} |
||||
|
||||
/*
|
||||
* Reset buffer descriptor as empty |
||||
*/ |
||||
mpc512x_fec_rbd_clean (fec, pRbd); |
||||
} |
||||
|
||||
/* Try to fill Buffer Descriptors */ |
||||
fec->eth->r_des_active = 0x01000000; /* Descriptor polling active */ |
||||
return len; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
int mpc512x_fec_initialize (bd_t * bis) |
||||
{ |
||||
|
||||
immap_t *im = (immap_t*) CFG_IMMR; |
||||
mpc512x_fec_priv *fec; |
||||
struct eth_device *dev; |
||||
int i; |
||||
char *tmp, *end, env_enetaddr[6]; |
||||
uint32 *reg; |
||||
void * bd; |
||||
|
||||
fec = (mpc512x_fec_priv *) malloc (sizeof(*fec)); |
||||
dev = (struct eth_device *) malloc (sizeof(*dev)); |
||||
memset (dev, 0, sizeof *dev); |
||||
|
||||
fec->eth = (ethernet_regs *) MPC512X_FEC; |
||||
|
||||
# ifndef CONFIG_FEC_10MBIT |
||||
fec->xcv_type = MII100; |
||||
# else |
||||
fec->xcv_type = MII10; |
||||
# endif |
||||
dev->priv = (void *)fec; |
||||
dev->iobase = MPC512X_FEC; |
||||
dev->init = mpc512x_fec_init; |
||||
dev->halt = mpc512x_fec_halt; |
||||
dev->send = mpc512x_fec_send; |
||||
dev->recv = mpc512x_fec_recv; |
||||
|
||||
sprintf (dev->name, "FEC ETHERNET"); |
||||
eth_register (dev); |
||||
|
||||
#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII) |
||||
miiphy_register (dev->name, |
||||
fec512x_miiphy_read, fec512x_miiphy_write); |
||||
#endif |
||||
|
||||
/*
|
||||
* Initialize I\O pins |
||||
*/ |
||||
reg = (uint32 *) &(im->io_ctrl.regs[PSC0_0_IDX]); |
||||
|
||||
for (i = 0; i < 15; i++) |
||||
reg[i] = IOCTRL_MUX_FEC | 0x00000001; |
||||
|
||||
im->io_ctrl.regs[SPDIF_TXCLOCK_IDX] = IOCTRL_MUX_FEC | 0x00000001; |
||||
im->io_ctrl.regs[SPDIF_TX_IDX] = IOCTRL_MUX_FEC | 0x00000001; |
||||
im->io_ctrl.regs[SPDIF_RX_IDX] = IOCTRL_MUX_FEC | 0x00000001; |
||||
|
||||
/* Clean up space FEC's MIB and FIFO RAM ...*/ |
||||
memset ((void *) MPC512X_FEC + 0x200, 0x00, 0x400); |
||||
|
||||
/*
|
||||
* Malloc space for BDs (must be quad word-aligned) |
||||
* this pointer is lost, so cannot be freed
|
||||
*/ |
||||
bd = malloc (sizeof(mpc512x_buff_descs) + 0x1f); |
||||
fec->bdBase = (mpc512x_buff_descs*)((uint32)bd & 0xfffffff0);
|
||||
memset ((void *) bd, 0x00, sizeof(mpc512x_buff_descs) + 0x1f); |
||||
|
||||
/*
|
||||
* Set interrupt mask register |
||||
*/ |
||||
fec->eth->imask = 0x00000000; |
||||
|
||||
/*
|
||||
* Clear FEC-Lite interrupt event register(IEVENT) |
||||
*/ |
||||
fec->eth->ievent = 0xffffffff; |
||||
|
||||
/*
|
||||
* Try to set the mac address now. The fec mac address is |
||||
* a garbage after reset. When not using fec for booting |
||||
* the Linux fec driver will try to work with this garbage. |
||||
*/ |
||||
tmp = getenv ("ethaddr"); |
||||
if (tmp) { |
||||
for (i=0; i<6; i++) { |
||||
env_enetaddr[i] = tmp ? simple_strtoul (tmp, &end, 16) : 0; |
||||
if (tmp) |
||||
tmp = (*end) ? end+1 : end; |
||||
} |
||||
mpc512x_fec_set_hwaddr (fec, env_enetaddr); |
||||
fec->eth->gaddr1 = 0x00000000; |
||||
fec->eth->gaddr2 = 0x00000000; |
||||
} |
||||
|
||||
mpc512x_fec_init_phy (dev, bis); |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
/* MII-interface related functions */ |
||||
/********************************************************************/ |
||||
int fec512x_miiphy_read (char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal) |
||||
{ |
||||
ethernet_regs *eth = (ethernet_regs *) MPC512X_FEC; |
||||
uint32 reg; /* convenient holder for the PHY register */ |
||||
uint32 phy; /* convenient holder for the PHY */ |
||||
int timeout = 0xffff; |
||||
|
||||
/*
|
||||
* reading from any PHY's register is done by properly |
||||
* programming the FEC's MII data register. |
||||
*/ |
||||
reg = regAddr << FEC_MII_DATA_RA_SHIFT; |
||||
phy = phyAddr << FEC_MII_DATA_PA_SHIFT; |
||||
|
||||
eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA | phy | reg); |
||||
|
||||
/*
|
||||
* wait for the related interrupt |
||||
*/ |
||||
while ((timeout--) && (!(eth->ievent & 0x00800000))) ; |
||||
|
||||
if (timeout == 0) { |
||||
#if (DEBUG & 0x2) |
||||
printf ("Read MDIO failed...\n"); |
||||
#endif |
||||
return -1; |
||||
} |
||||
|
||||
/*
|
||||
* clear mii interrupt bit |
||||
*/ |
||||
eth->ievent = 0x00800000; |
||||
|
||||
/*
|
||||
* it's now safe to read the PHY's register |
||||
*/ |
||||
*retVal = (uint16) eth->mii_data; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
int fec512x_miiphy_write (char *devname, uint8 phyAddr, uint8 regAddr, uint16 data) |
||||
{ |
||||
ethernet_regs *eth = (ethernet_regs *) MPC512X_FEC; |
||||
uint32 reg; /* convenient holder for the PHY register */ |
||||
uint32 phy; /* convenient holder for the PHY */ |
||||
int timeout = 0xffff; |
||||
|
||||
reg = regAddr << FEC_MII_DATA_RA_SHIFT; |
||||
phy = phyAddr << FEC_MII_DATA_PA_SHIFT; |
||||
|
||||
eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR | |
||||
FEC_MII_DATA_TA | phy | reg | data); |
||||
|
||||
/*
|
||||
* wait for the MII interrupt |
||||
*/ |
||||
while ((timeout--) && (!(eth->ievent & 0x00800000))) ; |
||||
|
||||
if (timeout == 0) { |
||||
#if (DEBUG & 0x2) |
||||
printf ("Write MDIO failed...\n"); |
||||
#endif |
||||
return -1; |
||||
} |
||||
|
||||
/*
|
||||
* clear MII interrupt bit |
||||
*/ |
||||
eth->ievent = 0x00800000; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
#if (DEBUG & 0x40) |
||||
static uint32 local_crc32 (char *string, unsigned int crc_value, int len) |
||||
{ |
||||
int i; |
||||
char c; |
||||
unsigned int crc, count; |
||||
|
||||
/*
|
||||
* crc32 algorithm |
||||
*/ |
||||
/*
|
||||
* crc = 0xffffffff; * The initialized value should be 0xffffffff |
||||
*/ |
||||
crc = crc_value; |
||||
|
||||
for (i = len; --i >= 0;) { |
||||
c = *string++; |
||||
for (count = 0; count < 8; count++) { |
||||
if ((c & 0x01) ^ (crc & 0x01)) { |
||||
crc >>= 1; |
||||
crc = crc ^ 0xedb88320; |
||||
} else { |
||||
crc >>= 1; |
||||
} |
||||
c >>= 1; |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
* In big endian system, do byte swaping for crc value |
||||
*/ |
||||
/**/ return crc; |
||||
} |
||||
#endif /* DEBUG */ |
||||
|
||||
#endif /* CONFIG_MPC512x_FEC */ |
@ -0,0 +1,224 @@ |
||||
/*
|
||||
* (C) Copyright 2003 - 2007 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* Derived from the MPC8xx driver's header file. |
||||
*/ |
||||
|
||||
#ifndef __MPC512X_FEC_H |
||||
#define __MPC512X_FEC_H |
||||
|
||||
#include <common.h> |
||||
#include <mpc512x.h> |
||||
|
||||
typedef unsigned long uint32; |
||||
typedef unsigned short uint16; |
||||
typedef unsigned char uint8; |
||||
|
||||
typedef struct ethernet_register_set { |
||||
|
||||
/* [10:2]addr = 00 */ |
||||
|
||||
/* Control and status Registers (offset 000-1FF) */ |
||||
|
||||
volatile uint32 fec_id; /* MBAR_ETH + 0x000 */ |
||||
volatile uint32 ievent; /* MBAR_ETH + 0x004 */ |
||||
volatile uint32 imask; /* MBAR_ETH + 0x008 */ |
||||
|
||||
volatile uint32 RES0[1]; /* MBAR_ETH + 0x00C */ |
||||
volatile uint32 r_des_active; /* MBAR_ETH + 0x010 */ |
||||
volatile uint32 x_des_active; /* MBAR_ETH + 0x014 */ |
||||
|
||||
volatile uint32 RES1[3]; /* MBAR_ETH + 0x018-020 */ |
||||
volatile uint32 ecntrl; /* MBAR_ETH + 0x024 */ |
||||
|
||||
volatile uint32 RES2[6]; /* MBAR_ETH + 0x028-03C */ |
||||
volatile uint32 mii_data; /* MBAR_ETH + 0x040 */ |
||||
volatile uint32 mii_speed; /* MBAR_ETH + 0x044 */ |
||||
|
||||
volatile uint32 RES3[7]; /* MBAR_ETH + 0x048-060 */ |
||||
volatile uint32 mib_control; /* MBAR_ETH + 0x064 */ |
||||
|
||||
volatile uint32 RES4[7]; /* MBAR_ETH + 0x068-80 */ |
||||
volatile uint32 r_cntrl; /* MBAR_ETH + 0x084 */ |
||||
volatile uint32 r_hash; /* MBAR_ETH + 0x088 */ |
||||
|
||||
volatile uint32 RES5[14]; /* MBAR_ETH + 0x08c-0C0 */ |
||||
volatile uint32 x_cntrl; /* MBAR_ETH + 0x0C4 */ |
||||
|
||||
volatile uint32 RES6[7]; /* MBAR_ETH + 0x0C8-0E0 */ |
||||
volatile uint32 paddr1; /* MBAR_ETH + 0x0E4 */ |
||||
volatile uint32 paddr2; /* MBAR_ETH + 0x0E8 */ |
||||
volatile uint32 op_pause; /* MBAR_ETH + 0x0EC */ |
||||
|
||||
volatile uint32 RES7[10]; /* MBAR_ETH + 0x0F0-114 */ |
||||
volatile uint32 iaddr1; /* MBAR_ETH + 0x118 */ |
||||
volatile uint32 iaddr2; /* MBAR_ETH + 0x11C */ |
||||
volatile uint32 gaddr1; /* MBAR_ETH + 0x120 */ |
||||
volatile uint32 gaddr2; /* MBAR_ETH + 0x124 */ |
||||
|
||||
volatile uint32 RES8[6]; /* MBAR_ETH + 0x128-13C */ |
||||
volatile uint32 fifo_id; /* MBAR_ETH + 0x140 */ |
||||
volatile uint32 x_wmrk; /* MBAR_ETH + 0x144 */ |
||||
volatile uint32 RES9[1]; /* MBAR_ETH + 0x148 */ |
||||
volatile uint32 r_bound; /* MBAR_ETH + 0x14C */ |
||||
volatile uint32 r_fstart; /* MBAR_ETH + 0x150 */ |
||||
|
||||
volatile uint32 RES10[11]; /* MBAR_ETH + 0x154-17C */ |
||||
volatile uint32 r_des_start; /* MBAR_ETH + 0x180 */ |
||||
volatile uint32 x_des_start; /* MBAR_ETH + 0x184 */ |
||||
volatile uint32 r_buff_size; /* MBAR_ETH + 0x188 */ |
||||
volatile uint32 RES11[26]; /* MBAR_ETH + 0x18C-1F0 */ |
||||
volatile uint32 dma_control; /* MBAR_ETH + 0x1F4 */ |
||||
volatile uint32 RES12[2]; /* MBAR_ETH + 0x1F8-1FC */ |
||||
|
||||
/* MIB COUNTERS (Offset 200-2FF) */ |
||||
|
||||
volatile uint32 rmon_t_drop; /* MBAR_ETH + 0x200 */ |
||||
volatile uint32 rmon_t_packets; /* MBAR_ETH + 0x204 */ |
||||
volatile uint32 rmon_t_bc_pkt; /* MBAR_ETH + 0x208 */ |
||||
volatile uint32 rmon_t_mc_pkt; /* MBAR_ETH + 0x20C */ |
||||
volatile uint32 rmon_t_crc_align; /* MBAR_ETH + 0x210 */ |
||||
volatile uint32 rmon_t_undersize; /* MBAR_ETH + 0x214 */ |
||||
volatile uint32 rmon_t_oversize; /* MBAR_ETH + 0x218 */ |
||||
volatile uint32 rmon_t_frag; /* MBAR_ETH + 0x21C */ |
||||
volatile uint32 rmon_t_jab; /* MBAR_ETH + 0x220 */ |
||||
volatile uint32 rmon_t_col; /* MBAR_ETH + 0x224 */ |
||||
volatile uint32 rmon_t_p64; /* MBAR_ETH + 0x228 */ |
||||
volatile uint32 rmon_t_p65to127; /* MBAR_ETH + 0x22C */ |
||||
volatile uint32 rmon_t_p128to255; /* MBAR_ETH + 0x230 */ |
||||
volatile uint32 rmon_t_p256to511; /* MBAR_ETH + 0x234 */ |
||||
volatile uint32 rmon_t_p512to1023; /* MBAR_ETH + 0x238 */ |
||||
volatile uint32 rmon_t_p1024to2047; /* MBAR_ETH + 0x23C */ |
||||
volatile uint32 rmon_t_p_gte2048; /* MBAR_ETH + 0x240 */ |
||||
volatile uint32 rmon_t_octets; /* MBAR_ETH + 0x244 */ |
||||
volatile uint32 ieee_t_drop; /* MBAR_ETH + 0x248 */ |
||||
volatile uint32 ieee_t_frame_ok; /* MBAR_ETH + 0x24C */ |
||||
volatile uint32 ieee_t_1col; /* MBAR_ETH + 0x250 */ |
||||
volatile uint32 ieee_t_mcol; /* MBAR_ETH + 0x254 */ |
||||
volatile uint32 ieee_t_def; /* MBAR_ETH + 0x258 */ |
||||
volatile uint32 ieee_t_lcol; /* MBAR_ETH + 0x25C */ |
||||
volatile uint32 ieee_t_excol; /* MBAR_ETH + 0x260 */ |
||||
volatile uint32 ieee_t_macerr; /* MBAR_ETH + 0x264 */ |
||||
volatile uint32 ieee_t_cserr; /* MBAR_ETH + 0x268 */ |
||||
volatile uint32 ieee_t_sqe; /* MBAR_ETH + 0x26C */ |
||||
volatile uint32 t_fdxfc; /* MBAR_ETH + 0x270 */ |
||||
volatile uint32 ieee_t_octets_ok; /* MBAR_ETH + 0x274 */ |
||||
|
||||
volatile uint32 RES13[2]; /* MBAR_ETH + 0x278-27C */ |
||||
volatile uint32 rmon_r_drop; /* MBAR_ETH + 0x280 */ |
||||
volatile uint32 rmon_r_packets; /* MBAR_ETH + 0x284 */ |
||||
volatile uint32 rmon_r_bc_pkt; /* MBAR_ETH + 0x288 */ |
||||
volatile uint32 rmon_r_mc_pkt; /* MBAR_ETH + 0x28C */ |
||||
volatile uint32 rmon_r_crc_align; /* MBAR_ETH + 0x290 */ |
||||
volatile uint32 rmon_r_undersize; /* MBAR_ETH + 0x294 */ |
||||
volatile uint32 rmon_r_oversize; /* MBAR_ETH + 0x298 */ |
||||
volatile uint32 rmon_r_frag; /* MBAR_ETH + 0x29C */ |
||||
volatile uint32 rmon_r_jab; /* MBAR_ETH + 0x2A0 */ |
||||
|
||||
volatile uint32 rmon_r_resvd_0; /* MBAR_ETH + 0x2A4 */ |
||||
|
||||
volatile uint32 rmon_r_p64; /* MBAR_ETH + 0x2A8 */ |
||||
volatile uint32 rmon_r_p65to127; /* MBAR_ETH + 0x2AC */ |
||||
volatile uint32 rmon_r_p128to255; /* MBAR_ETH + 0x2B0 */ |
||||
volatile uint32 rmon_r_p256to511; /* MBAR_ETH + 0x2B4 */ |
||||
volatile uint32 rmon_r_p512to1023; /* MBAR_ETH + 0x2B8 */ |
||||
volatile uint32 rmon_r_p1024to2047; /* MBAR_ETH + 0x2BC */ |
||||
volatile uint32 rmon_r_p_gte2048; /* MBAR_ETH + 0x2C0 */ |
||||
volatile uint32 rmon_r_octets; /* MBAR_ETH + 0x2C4 */ |
||||
volatile uint32 ieee_r_drop; /* MBAR_ETH + 0x2C8 */ |
||||
volatile uint32 ieee_r_frame_ok; /* MBAR_ETH + 0x2CC */ |
||||
volatile uint32 ieee_r_crc; /* MBAR_ETH + 0x2D0 */ |
||||
volatile uint32 ieee_r_align; /* MBAR_ETH + 0x2D4 */ |
||||
volatile uint32 r_macerr; /* MBAR_ETH + 0x2D8 */ |
||||
volatile uint32 r_fdxfc; /* MBAR_ETH + 0x2DC */ |
||||
volatile uint32 ieee_r_octets_ok; /* MBAR_ETH + 0x2E0 */ |
||||
|
||||
volatile uint32 RES14[6]; /* MBAR_ETH + 0x2E4-2FC */ |
||||
|
||||
volatile uint32 RES15[64]; /* MBAR_ETH + 0x300-3FF */ |
||||
} ethernet_regs; |
||||
|
||||
/* Receive & Transmit Buffer Descriptor definitions */ |
||||
typedef struct BufferDescriptor { |
||||
uint16 status; |
||||
uint16 dataLength; |
||||
uint32 dataPointer; |
||||
} FEC_RBD; |
||||
|
||||
typedef struct { |
||||
uint16 status; |
||||
uint16 dataLength; |
||||
uint32 dataPointer; |
||||
} FEC_TBD; |
||||
|
||||
/* private structure */ |
||||
typedef enum { |
||||
SEVENWIRE, /* 7-wire */ |
||||
MII10, /* MII 10Mbps */ |
||||
MII100 /* MII 100Mbps */ |
||||
} xceiver_type; |
||||
|
||||
/* BD Numer definitions */ |
||||
#define FEC_TBD_NUM 48 /* The user can adjust this value */ |
||||
#define FEC_RBD_NUM 32 /* The user can adjust this value */ |
||||
|
||||
/* packet size limit */ |
||||
#define FEC_MAX_PKT_SIZE 1536 |
||||
|
||||
typedef struct { |
||||
uint8 frame[FEC_MAX_PKT_SIZE]; |
||||
} mpc512x_frame; |
||||
|
||||
typedef struct { |
||||
FEC_RBD rbd[FEC_RBD_NUM]; /* RBD ring */ |
||||
FEC_TBD tbd[FEC_TBD_NUM]; /* TBD ring */ |
||||
mpc512x_frame recv_frames[FEC_RBD_NUM]; /* receive buff */ |
||||
} mpc512x_buff_descs; |
||||
|
||||
typedef struct { |
||||
ethernet_regs *eth; |
||||
xceiver_type xcv_type; /* transceiver type */ |
||||
mpc512x_buff_descs *bdBase; /* BD rings and recv buffer */ |
||||
uint16 rbdIndex; /* next receive BD to read */ |
||||
uint16 tbdIndex; /* next transmit BD to send */ |
||||
uint16 usedTbdIndex; /* next transmit BD to clean */ |
||||
uint16 cleanTbdNum; /* the number of available transmit BDs */ |
||||
} mpc512x_fec_priv; |
||||
|
||||
/* RBD bits definitions */ |
||||
#define FEC_RBD_EMPTY 0x8000 /* Buffer is empty */ |
||||
#define FEC_RBD_WRAP 0x2000 /* Last BD in ring */ |
||||
#define FEC_RBD_LAST 0x0800 /* Buffer is last in frame(useless) */ |
||||
#define FEC_RBD_MISS 0x0100 /* Miss bit for prom mode */ |
||||
#define FEC_RBD_BC 0x0080 /* The received frame is broadcast frame */ |
||||
#define FEC_RBD_MC 0x0040 /* The received frame is multicast frame */ |
||||
#define FEC_RBD_LG 0x0020 /* Frame length violation */ |
||||
#define FEC_RBD_NO 0x0010 /* Nonoctet align frame */ |
||||
#define FEC_RBD_SH 0x0008 /* Short frame */ |
||||
#define FEC_RBD_CR 0x0004 /* CRC error */ |
||||
#define FEC_RBD_OV 0x0002 /* Receive FIFO overrun */ |
||||
#define FEC_RBD_TR 0x0001 /* Frame is truncated */ |
||||
#define FEC_RBD_ERR (FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \ |
||||
FEC_RBD_OV | FEC_RBD_TR) |
||||
|
||||
/* TBD bits definitions */ |
||||
#define FEC_TBD_READY 0x8000 /* Buffer is ready */ |
||||
#define FEC_TBD_WRAP 0x2000 /* Last BD in ring */ |
||||
#define FEC_TBD_LAST 0x0800 /* Buffer is last in frame */ |
||||
#define FEC_TBD_TC 0x0400 /* Transmit the CRC */ |
||||
#define FEC_TBD_ABC 0x0200 /* Append bad CRC */ |
||||
|
||||
/* MII-related definitios */ |
||||
#define FEC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */ |
||||
#define FEC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */ |
||||
#define FEC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */ |
||||
#define FEC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */ |
||||
#define FEC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */ |
||||
#define FEC_MII_DATA_TA 0x00020000 /* Turnaround */ |
||||
#define FEC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */ |
||||
|
||||
#define FEC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */ |
||||
#define FEC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */ |
||||
|
||||
#endif /* __MPC512X_FEC_H */ |
@ -0,0 +1,431 @@ |
||||
/*
|
||||
* (C) Copyright 2003 - 2007 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
* Based on the MPC5xxx code. |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#ifdef CONFIG_HARD_I2C |
||||
|
||||
#include <mpc512x.h> |
||||
#include <i2c.h> |
||||
|
||||
#define immr ((immap_t *)CFG_IMMR) |
||||
|
||||
/* by default set I2C bus 0 active */ |
||||
static unsigned int bus_num = 0; |
||||
|
||||
#define I2C_TIMEOUT 100 |
||||
#define I2C_RETRIES 3 |
||||
|
||||
struct mpc512x_i2c_tap { |
||||
int scl2tap; |
||||
int tap2tap; |
||||
}; |
||||
|
||||
static int mpc_reg_in(volatile u32 *reg); |
||||
static void mpc_reg_out(volatile u32 *reg, int val, int mask); |
||||
static int wait_for_bb(void); |
||||
static int wait_for_pin(int *status); |
||||
static int do_address(uchar chip, char rdwr_flag); |
||||
static int send_bytes(uchar chip, char *buf, int len); |
||||
static int receive_bytes(uchar chip, char *buf, int len); |
||||
static int mpc_get_fdr(int); |
||||
|
||||
static int mpc_reg_in (volatile u32 *reg) |
||||
{ |
||||
int ret = *reg >> 24; |
||||
__asm__ __volatile__ ("eieio"); |
||||
return ret; |
||||
} |
||||
|
||||
static void mpc_reg_out (volatile u32 *reg, int val, int mask) |
||||
{ |
||||
int tmp; |
||||
|
||||
if (!mask) { |
||||
*reg = val << 24; |
||||
} else { |
||||
tmp = mpc_reg_in (reg); |
||||
*reg = ((tmp & ~mask) | (val & mask)) << 24; |
||||
} |
||||
__asm__ __volatile__ ("eieio"); |
||||
|
||||
return; |
||||
} |
||||
|
||||
static int wait_for_bb (void) |
||||
{ |
||||
i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; |
||||
int timeout = I2C_TIMEOUT; |
||||
int status; |
||||
|
||||
status = mpc_reg_in (®s->msr); |
||||
|
||||
while (timeout-- && (status & I2C_BB)) { |
||||
volatile int temp; |
||||
mpc_reg_out (®s->mcr, I2C_STA, I2C_STA); |
||||
temp = mpc_reg_in (®s->mdr); |
||||
mpc_reg_out (®s->mcr, 0, I2C_STA); |
||||
mpc_reg_out (®s->mcr, 0, 0); |
||||
mpc_reg_out (®s->mcr, I2C_EN, 0); |
||||
|
||||
udelay (1000); |
||||
status = mpc_reg_in (®s->msr); |
||||
} |
||||
|
||||
return (status & I2C_BB); |
||||
} |
||||
|
||||
static int wait_for_pin (int *status) |
||||
{ |
||||
i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; |
||||
int timeout = I2C_TIMEOUT; |
||||
|
||||
*status = mpc_reg_in (®s->msr); |
||||
|
||||
while (timeout-- && !(*status & I2C_IF)) { |
||||
udelay (1000); |
||||
*status = mpc_reg_in (®s->msr); |
||||
} |
||||
|
||||
if (!(*status & I2C_IF)) { |
||||
return -1; |
||||
} |
||||
|
||||
mpc_reg_out (®s->msr, 0, I2C_IF); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int do_address (uchar chip, char rdwr_flag) |
||||
{ |
||||
i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; |
||||
int status; |
||||
|
||||
chip <<= 1; |
||||
|
||||
if (rdwr_flag) { |
||||
chip |= 1; |
||||
} |
||||
|
||||
mpc_reg_out (®s->mcr, I2C_TX, I2C_TX); |
||||
mpc_reg_out (®s->mdr, chip, 0); |
||||
|
||||
if (wait_for_pin (&status)) { |
||||
return -2; |
||||
} |
||||
|
||||
if (status & I2C_RXAK) { |
||||
return -3; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int send_bytes (uchar chip, char *buf, int len) |
||||
{ |
||||
i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; |
||||
int wrcount; |
||||
int status; |
||||
|
||||
for (wrcount = 0; wrcount < len; ++wrcount) { |
||||
|
||||
mpc_reg_out (®s->mdr, buf[wrcount], 0); |
||||
|
||||
if (wait_for_pin (&status)) { |
||||
break; |
||||
} |
||||
|
||||
if (status & I2C_RXAK) { |
||||
break; |
||||
} |
||||
|
||||
} |
||||
|
||||
return !(wrcount == len); |
||||
} |
||||
|
||||
static int receive_bytes (uchar chip, char *buf, int len) |
||||
{ |
||||
i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; |
||||
int dummy = 1; |
||||
int rdcount = 0; |
||||
int status; |
||||
int i; |
||||
|
||||
mpc_reg_out (®s->mcr, 0, I2C_TX); |
||||
|
||||
for (i = 0; i < len; ++i) { |
||||
buf[rdcount] = mpc_reg_in (®s->mdr); |
||||
|
||||
if (dummy) { |
||||
dummy = 0; |
||||
} else { |
||||
rdcount++; |
||||
} |
||||
|
||||
if (wait_for_pin (&status)) { |
||||
return -4; |
||||
} |
||||
} |
||||
|
||||
mpc_reg_out (®s->mcr, I2C_TXAK, I2C_TXAK); |
||||
buf[rdcount++] = mpc_reg_in (®s->mdr); |
||||
|
||||
if (wait_for_pin (&status)) { |
||||
return -5; |
||||
} |
||||
|
||||
mpc_reg_out (®s->mcr, 0, I2C_TXAK); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/**************** I2C API ****************/ |
||||
|
||||
void i2c_init (int speed, int saddr) |
||||
{ |
||||
int i; |
||||
for(i = 0; i < I2C_BUS_CNT; i++){ |
||||
i2c512x_dev_t *regs = &immr->i2c.dev[i]; |
||||
mpc_reg_out (®s->mcr, 0, 0); |
||||
|
||||
/* Set clock */ |
||||
mpc_reg_out (®s->mfdr, mpc_get_fdr (speed), 0); |
||||
mpc_reg_out (®s->madr, saddr << 1, 0); |
||||
|
||||
/* Enable module */ |
||||
mpc_reg_out (®s->mcr, I2C_EN, I2C_INIT_MASK); |
||||
mpc_reg_out (®s->msr, 0, I2C_IF); |
||||
} |
||||
|
||||
/* Disable interrupts */ |
||||
immr->i2c.icr = 0; |
||||
/* Turn off filters */ |
||||
immr->i2c.mifr = 0; |
||||
return; |
||||
} |
||||
|
||||
static int mpc_get_fdr (int speed) |
||||
{ |
||||
static int fdr = -1; |
||||
|
||||
if (fdr == -1) { |
||||
ulong best_speed = 0; |
||||
ulong divider; |
||||
ulong ipb, scl; |
||||
ulong bestmatch = 0xffffffffUL; |
||||
int best_i = 0, best_j = 0, i, j; |
||||
int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8}; |
||||
struct mpc512x_i2c_tap scltap[] = { |
||||
{4, 1}, |
||||
{4, 2}, |
||||
{6, 4}, |
||||
{6, 8}, |
||||
{14, 16}, |
||||
{30, 32}, |
||||
{62, 64}, |
||||
{126, 128} |
||||
}; |
||||
|
||||
ipb = gd->ipb_clk; |
||||
for (i = 7; i >= 0; i--) { |
||||
for (j = 7; j >= 0; j--) { |
||||
scl = 2 * (scltap[j].scl2tap + |
||||
(SCL_Tap[i] - 1) * scltap[j].tap2tap |
||||
+ 2); |
||||
if (ipb <= speed*scl) { |
||||
if ((speed*scl - ipb) < bestmatch) { |
||||
bestmatch = speed*scl - ipb; |
||||
best_i = i; |
||||
best_j = j; |
||||
best_speed = ipb/scl; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
divider = (best_i & 3) | ((best_i & 4) << 3) | (best_j << 2); |
||||
if (gd->flags & GD_FLG_RELOC) { |
||||
fdr = divider; |
||||
} else { |
||||
debug("%ld kHz, \n", best_speed / 1000); |
||||
return divider; |
||||
} |
||||
} |
||||
|
||||
return fdr; |
||||
} |
||||
|
||||
int i2c_probe (uchar chip) |
||||
{ |
||||
i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; |
||||
int i; |
||||
|
||||
for (i = 0; i < I2C_RETRIES; i++) { |
||||
mpc_reg_out (®s->mcr, I2C_STA, I2C_STA); |
||||
|
||||
if (! do_address (chip, 0)) { |
||||
mpc_reg_out (®s->mcr, 0, I2C_STA); |
||||
udelay (500); |
||||
break; |
||||
} |
||||
|
||||
mpc_reg_out (®s->mcr, 0, I2C_STA); |
||||
udelay (500); |
||||
} |
||||
|
||||
return (i == I2C_RETRIES); |
||||
} |
||||
|
||||
int i2c_read (uchar chip, uint addr, int alen, uchar *buf, int len) |
||||
{ |
||||
char xaddr[4]; |
||||
i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; |
||||
int ret = -1; |
||||
|
||||
xaddr[0] = (addr >> 24) & 0xFF; |
||||
xaddr[1] = (addr >> 16) & 0xFF; |
||||
xaddr[2] = (addr >> 8) & 0xFF; |
||||
xaddr[3] = addr & 0xFF; |
||||
|
||||
if (wait_for_bb ()) { |
||||
printf ("i2c_read: bus is busy\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
mpc_reg_out (®s->mcr, I2C_STA, I2C_STA); |
||||
if (do_address (chip, 0)) { |
||||
printf ("i2c_read: failed to address chip\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
if (send_bytes (chip, &xaddr[4-alen], alen)) { |
||||
printf ("i2c_read: send_bytes failed\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
mpc_reg_out (®s->mcr, I2C_RSTA, I2C_RSTA); |
||||
if (do_address (chip, 1)) { |
||||
printf ("i2c_read: failed to address chip\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
if (receive_bytes (chip, (char *)buf, len)) { |
||||
printf ("i2c_read: receive_bytes failed\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
ret = 0; |
||||
Done: |
||||
mpc_reg_out (®s->mcr, 0, I2C_STA); |
||||
return ret; |
||||
} |
||||
|
||||
int i2c_write (uchar chip, uint addr, int alen, uchar *buf, int len) |
||||
{ |
||||
char xaddr[4]; |
||||
i2c512x_dev_t *regs = &immr->i2c.dev[bus_num]; |
||||
int ret = -1; |
||||
|
||||
xaddr[0] = (addr >> 24) & 0xFF; |
||||
xaddr[1] = (addr >> 16) & 0xFF; |
||||
xaddr[2] = (addr >> 8) & 0xFF; |
||||
xaddr[3] = addr & 0xFF; |
||||
|
||||
if (wait_for_bb ()) { |
||||
printf ("i2c_write: bus is busy\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
mpc_reg_out (®s->mcr, I2C_STA, I2C_STA); |
||||
if (do_address (chip, 0)) { |
||||
printf ("i2c_write: failed to address chip\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
if (send_bytes (chip, &xaddr[4-alen], alen)) { |
||||
printf ("i2c_write: send_bytes failed\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
if (send_bytes (chip, (char *)buf, len)) { |
||||
printf ("i2c_write: send_bytes failed\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
ret = 0; |
||||
Done: |
||||
mpc_reg_out (®s->mcr, 0, I2C_STA); |
||||
return ret; |
||||
} |
||||
|
||||
uchar i2c_reg_read (uchar chip, uchar reg) |
||||
{ |
||||
uchar buf; |
||||
|
||||
i2c_read (chip, reg, 1, &buf, 1); |
||||
|
||||
return buf; |
||||
} |
||||
|
||||
void i2c_reg_write (uchar chip, uchar reg, uchar val) |
||||
{ |
||||
i2c_write (chip, reg, 1, &val, 1); |
||||
|
||||
return; |
||||
} |
||||
|
||||
|
||||
int i2c_set_bus_num (unsigned int bus) |
||||
{ |
||||
if (bus >= I2C_BUS_CNT) { |
||||
return -1; |
||||
} |
||||
bus_num = bus; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
unsigned int i2c_get_bus_num (void) |
||||
{ |
||||
return bus_num; |
||||
} |
||||
|
||||
/* TODO */ |
||||
unsigned int i2c_get_bus_speed (void) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
int i2c_set_bus_speed (unsigned int speed) |
||||
{ |
||||
if (speed != CFG_I2C_SPEED) |
||||
return -1; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
#endif /* CONFIG_HARD_I2C */ |
@ -0,0 +1,61 @@ |
||||
/*
|
||||
* (C) Copyright 2000-2007 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* Copyright 2004 Freescale Semiconductor, Inc. |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
* Derived from the MPC83xx code. |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
struct irq_action { |
||||
interrupt_handler_t *handler; |
||||
void *arg; |
||||
ulong count; |
||||
}; |
||||
|
||||
int interrupt_init_cpu (unsigned *decrementer_count) |
||||
{ |
||||
*decrementer_count = get_tbclk () / CFG_HZ; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/*
|
||||
* Install and free an interrupt handler. |
||||
*/ |
||||
void |
||||
irq_install_handler (int irq, interrupt_handler_t * handler, void *arg) |
||||
{ |
||||
} |
||||
|
||||
void irq_free_handler (int irq) |
||||
{ |
||||
} |
||||
|
||||
void timer_interrupt_cpu (struct pt_regs *regs) |
||||
{ |
||||
/* nothing to do here */ |
||||
return; |
||||
} |
@ -0,0 +1,197 @@ |
||||
/*
|
||||
* (C) Copyright 2000 - 2007 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
* Based ont the MPC5200 PSC driver. |
||||
* Adapted for MPC512x by Jan Wrobel <wrr@semihalf.com> |
||||
*/ |
||||
|
||||
/*
|
||||
* Minimal serial functions needed to use one of the PSC ports |
||||
* as serial console interface. |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#if defined(CONFIG_PSC_CONSOLE) |
||||
|
||||
static void fifo_init (volatile psc512x_t *psc) |
||||
{ |
||||
volatile immap_t *im = (immap_t *) CFG_IMMR; |
||||
|
||||
/* reset Rx & Tx fifo slice */ |
||||
psc->rfcmd = PSC_FIFO_RESET_SLICE; |
||||
psc->tfcmd = PSC_FIFO_RESET_SLICE; |
||||
|
||||
/* disable Tx & Rx FIFO interrupts */ |
||||
psc->rfintmask = 0; |
||||
psc->tfintmask = 0; |
||||
|
||||
psc->tfsize = CONSOLE_FIFO_TX_SIZE | (CONSOLE_FIFO_TX_ADDR << 16); |
||||
psc->rfsize = CONSOLE_FIFO_RX_SIZE | (CONSOLE_FIFO_RX_ADDR << 16); |
||||
|
||||
/* enable Tx & Rx FIFO slice */ |
||||
psc->rfcmd = PSC_FIFO_ENABLE_SLICE; |
||||
psc->tfcmd = PSC_FIFO_ENABLE_SLICE; |
||||
|
||||
im->fifoc.fifoc_cmd = FIFOC_DISABLE_CLOCK_GATE; |
||||
__asm__ volatile ("sync"); |
||||
} |
||||
|
||||
int serial_init(void) |
||||
{ |
||||
volatile immap_t *im = (immap_t *) CFG_IMMR; |
||||
volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
||||
unsigned long baseclk; |
||||
int div; |
||||
|
||||
fifo_init (psc); |
||||
|
||||
/* set MR register to point to MR1 */ |
||||
psc->command = PSC_SEL_MODE_REG_1; |
||||
|
||||
/* disable Tx/Rx */ |
||||
psc->command = PSC_TX_DISABLE | PSC_RX_DISABLE; |
||||
|
||||
/* choose the prescaler by 16 for the Tx/Rx clock generation */ |
||||
psc->psc_clock_select = 0xdd00; |
||||
|
||||
/* switch to UART mode */ |
||||
psc->sicr = 0; |
||||
|
||||
/* mode register points to mr1 */ |
||||
/* configure parity, bit length and so on in mode register 1*/ |
||||
psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE; |
||||
/* now, mode register points to mr2 */ |
||||
psc->mode = PSC_MODE_1_STOPBIT; |
||||
|
||||
/* calculate dividor for setting PSC CTUR and CTLR registers */ |
||||
baseclk = (gd->ipb_clk + 8) / 16; |
||||
div = (baseclk + (gd->baudrate / 2)) / gd->baudrate; |
||||
|
||||
psc->ctur = (div >> 8) & 0xff; |
||||
/* set baudrate */ |
||||
psc->ctlr = div & 0xff; |
||||
|
||||
/* disable all interrupts */ |
||||
psc->psc_imr = 0; |
||||
|
||||
/* reset and enable Rx/Tx */ |
||||
psc->command = PSC_RST_RX; |
||||
psc->command = PSC_RST_TX; |
||||
psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
void serial_putc (const char c) |
||||
{ |
||||
volatile immap_t *im = (immap_t *)CFG_IMMR; |
||||
volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
||||
|
||||
if (c == '\n') |
||||
serial_putc ('\r'); |
||||
|
||||
/* Wait for last character to go. */ |
||||
while (!(psc->psc_status & PSC_SR_TXEMP)) |
||||
; |
||||
|
||||
psc->tfdata_8 = c; |
||||
} |
||||
|
||||
void serial_putc_raw (const char c) |
||||
{ |
||||
volatile immap_t *im = (immap_t *) CFG_IMMR; |
||||
volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
||||
|
||||
/* Wait for last character to go. */ |
||||
while (!(psc->psc_status & PSC_SR_TXEMP)) |
||||
; |
||||
|
||||
psc->tfdata_8 = c; |
||||
} |
||||
|
||||
|
||||
void serial_puts (const char *s) |
||||
{ |
||||
while (*s) { |
||||
serial_putc (*s++); |
||||
} |
||||
} |
||||
|
||||
int serial_getc (void) |
||||
{ |
||||
volatile immap_t *im = (immap_t *) CFG_IMMR; |
||||
volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
||||
|
||||
/* Wait for a character to arrive. */ |
||||
while (psc->rfstat & PSC_FIFO_EMPTY) |
||||
; |
||||
|
||||
return psc->rfdata_8; |
||||
} |
||||
|
||||
int serial_tstc (void) |
||||
{ |
||||
volatile immap_t *im = (immap_t *) CFG_IMMR; |
||||
volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
||||
|
||||
return !(psc->rfstat & PSC_FIFO_EMPTY); |
||||
} |
||||
|
||||
void serial_setbrg (void) |
||||
{ |
||||
volatile immap_t *im = (immap_t *) CFG_IMMR; |
||||
volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
||||
unsigned long baseclk, div; |
||||
|
||||
baseclk = (gd->csb_clk + 8) / 16; |
||||
div = (baseclk + (gd->baudrate / 2)) / gd->baudrate; |
||||
|
||||
psc->ctur = (div >> 8) & 0xFF; |
||||
psc->ctlr = div & 0xff; /* set baudrate */ |
||||
} |
||||
|
||||
void serial_setrts(int s) |
||||
{ |
||||
volatile immap_t *im = (immap_t *) CFG_IMMR; |
||||
volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
||||
|
||||
if (s) { |
||||
/* Assert RTS (become LOW) */ |
||||
psc->op1 = 0x1; |
||||
} |
||||
else { |
||||
/* Negate RTS (become HIGH) */ |
||||
psc->op0 = 0x1; |
||||
} |
||||
} |
||||
|
||||
int serial_getcts(void) |
||||
{ |
||||
volatile immap_t *im = (immap_t *) CFG_IMMR; |
||||
volatile psc512x_t *psc = (psc512x_t *) &im->psc[CONFIG_PSC_CONSOLE]; |
||||
|
||||
return (psc->ip & 0x1) ? 0 : 1; |
||||
} |
||||
#endif /* CONFIG_PSC_CONSOLE */ |
@ -0,0 +1,135 @@ |
||||
/*
|
||||
* (C) Copyright 2000-2007 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* Copyright (C) 2004-2006 Freescale Semiconductor, Inc. |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
* Based on the MPC83xx code. |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <mpc512x.h> |
||||
#include <command.h> |
||||
#include <asm/processor.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
static int spmf_mult[] = { |
||||
68, 1, 12, 16, |
||||
20, 24, 28, 32, |
||||
36, 40, 44, 48, |
||||
52, 56, 60, 64 |
||||
}; |
||||
|
||||
static int cpmf_mult[][2] = { |
||||
{0, 1}, {0, 1}, /* 0 and 1 are not valid */ |
||||
{1, 1}, {3, 2}, |
||||
{2, 1}, {5, 2}, |
||||
{3, 1}, {7, 2}, |
||||
{0, 1}, {0, 1}, /* and all above 7 are not valid too */ |
||||
{0, 1}, {0, 1}, |
||||
{0, 1}, {0, 1}, |
||||
{0, 1}, {0, 1} |
||||
}; |
||||
|
||||
static int sys_dividors[][2] = { |
||||
{2, 1}, {5, 2}, {3, 1}, {7, 2}, {4, 1}, |
||||
{9, 2}, {5, 1}, {7, 1}, {6, 1}, {8, 1}, |
||||
{9, 1}, {11, 1}, {10, 1}, {12, 1}, {13, 1}, |
||||
{15, 1}, {14, 1}, {16, 1}, {17, 1}, {19, 1}, |
||||
{18, 1}, {20, 1}, {21, 1}, {23, 1}, {22, 1}, |
||||
{24, 1}, {25, 1}, {27, 1}, {26, 1}, {28, 1}, |
||||
{29, 1}, {31, 1}, {30, 1}, {32, 1}, {33, 1} |
||||
}; |
||||
|
||||
int get_clocks (void) |
||||
{ |
||||
volatile immap_t *im = (immap_t *) CFG_IMMR; |
||||
u8 spmf; |
||||
u8 cpmf; |
||||
u8 sys_div; |
||||
u8 ips_div; |
||||
u32 ref_clk = CFG_MPC512X_CLKIN; |
||||
u32 spll; |
||||
u32 sys_clk; |
||||
u32 core_clk; |
||||
u32 csb_clk; |
||||
u32 ips_clk; |
||||
|
||||
if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im) |
||||
return -1; |
||||
|
||||
spmf = (im->clk.spmr & SPMR_SPMF) >> SPMR_SPMF_SHIFT; |
||||
spll = ref_clk * spmf_mult[spmf]; |
||||
|
||||
sys_div = (im->clk.scfr[1] & SCFR2_SYS_DIV) >> SCFR2_SYS_DIV_SHIFT; |
||||
sys_clk = (spll * sys_dividors[sys_div][1]) / sys_dividors[sys_div][0]; |
||||
|
||||
csb_clk = sys_clk / 2; |
||||
|
||||
cpmf = (im->clk.spmr & SPMR_CPMF) >> SPMR_CPMF_SHIFT; |
||||
core_clk = (csb_clk * cpmf_mult[cpmf][0]) / cpmf_mult[cpmf][1]; |
||||
|
||||
ips_div = (im->clk.scfr[0] & SCFR1_IPS_DIV_MASK) >> SCFR1_IPS_DIV_SHIFT; |
||||
if (ips_div != 0) { |
||||
ips_clk = csb_clk / ips_div; |
||||
} else { |
||||
/* in case we cannot get a sane IPS divisor, fail gracefully */ |
||||
ips_clk = 0; |
||||
} |
||||
|
||||
gd->ipb_clk = ips_clk; |
||||
gd->csb_clk = csb_clk; |
||||
gd->cpu_clk = core_clk; |
||||
gd->bus_clk = csb_clk; |
||||
return 0; |
||||
|
||||
} |
||||
|
||||
/********************************************
|
||||
* get_bus_freq |
||||
* return system bus freq in Hz |
||||
*********************************************/ |
||||
ulong get_bus_freq (ulong dummy) |
||||
{ |
||||
return gd->csb_clk; |
||||
} |
||||
|
||||
int do_clocks (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
||||
{ |
||||
printf ("Clock configuration:\n"); |
||||
printf (" CPU: %4d MHz\n", gd->cpu_clk / 1000000); |
||||
printf (" Coherent System Bus: %4d MHz\n", gd->csb_clk / 1000000); |
||||
printf (" IPS Bus: %4d MHz\n", gd->ipb_clk / 1000000); |
||||
printf (" DDR: %4d MHz\n", 2 * gd->csb_clk / 1000000); |
||||
return 0; |
||||
} |
||||
|
||||
U_BOOT_CMD(clocks, 1, 0, do_clocks, |
||||
"clocks - print clock configuration\n", |
||||
" clocks\n" |
||||
); |
||||
|
||||
int prt_mpc512x_clks (void) |
||||
{ |
||||
do_clocks (NULL, 0, 0, NULL); |
||||
return (0); |
||||
} |
@ -0,0 +1,780 @@ |
||||
/* |
||||
* Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
|
||||
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> |
||||
* Copyright (C) 2000, 2001, 2002, 2007 Wolfgang Denk <wd@denx.de>
|
||||
* Copyright Freescale Semiconductor, Inc. 2004, 2006. All rights reserved. |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
* Based on the MPC83xx code. |
||||
*/ |
||||
|
||||
/* |
||||
* U-Boot - Startup Code for MPC512x based Embedded Boards |
||||
*/ |
||||
|
||||
#include <config.h> |
||||
#include <mpc512x.h> |
||||
#include <version.h> |
||||
|
||||
#define CONFIG_521X 1 /* needed for Linux kernel header files*/ |
||||
|
||||
#include <ppc_asm.tmpl> |
||||
#include <ppc_defs.h> |
||||
|
||||
#include <asm/cache.h> |
||||
#include <asm/mmu.h> |
||||
|
||||
#ifndef CONFIG_IDENT_STRING |
||||
#define CONFIG_IDENT_STRING "MPC512X" |
||||
#endif |
||||
|
||||
/* |
||||
* Floating Point enable, Machine Check and Recoverable Interr. |
||||
*/ |
||||
#undef MSR_KERNEL |
||||
#ifdef DEBUG |
||||
#define MSR_KERNEL (MSR_FP|MSR_RI) |
||||
#else |
||||
#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI) |
||||
#endif |
||||
|
||||
/* Macros for manipulating CSx_START/STOP */ |
||||
#define START_REG(start) ((start) >> 16) |
||||
#define STOP_REG(start, size) (((start) + (size) - 1) >> 16) |
||||
|
||||
/* |
||||
* Set up GOT: Global Offset Table |
||||
* |
||||
* Use r14 to access the GOT |
||||
*/ |
||||
START_GOT |
||||
GOT_ENTRY(_GOT2_TABLE_) |
||||
GOT_ENTRY(_FIXUP_TABLE_) |
||||
|
||||
GOT_ENTRY(_start) |
||||
GOT_ENTRY(_start_of_vectors) |
||||
GOT_ENTRY(_end_of_vectors) |
||||
GOT_ENTRY(transfer_to_handler) |
||||
|
||||
GOT_ENTRY(__init_end) |
||||
GOT_ENTRY(_end) |
||||
GOT_ENTRY(__bss_start) |
||||
END_GOT |
||||
|
||||
/* |
||||
* Magic number and version string |
||||
*/ |
||||
.long 0x27051956 /* U-Boot Magic Number */ |
||||
.globl version_string
|
||||
version_string: |
||||
.ascii U_BOOT_VERSION
|
||||
.ascii " (", __DATE__, " - ", __TIME__, ")" |
||||
.ascii " ", CONFIG_IDENT_STRING, "\0" |
||||
|
||||
/* |
||||
* Vector Table |
||||
*/ |
||||
.text |
||||
. = EXC_OFF_SYS_RESET |
||||
|
||||
.globl _start
|
||||
/* Start from here after reset/power on */ |
||||
_start: |
||||
li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */ |
||||
b boot_cold |
||||
|
||||
.globl _start_of_vectors
|
||||
_start_of_vectors: |
||||
|
||||
/* Machine check */ |
||||
STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) |
||||
|
||||
/* Data Storage exception. */ |
||||
STD_EXCEPTION(0x300, DataStorage, UnknownException) |
||||
|
||||
/* Instruction Storage exception. */ |
||||
STD_EXCEPTION(0x400, InstStorage, UnknownException) |
||||
|
||||
/* External Interrupt exception. */ |
||||
STD_EXCEPTION(0x500, ExtInterrupt, UnknownException) |
||||
|
||||
/* Alignment exception. */ |
||||
. = 0x600 |
||||
Alignment: |
||||
EXCEPTION_PROLOG(SRR0, SRR1) |
||||
mfspr r4,DAR |
||||
stw r4,_DAR(r21) |
||||
mfspr r5,DSISR |
||||
stw r5,_DSISR(r21) |
||||
addi r3,r1,STACK_FRAME_OVERHEAD |
||||
li r20,MSR_KERNEL |
||||
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ |
||||
rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */ |
||||
lwz r6,GOT(transfer_to_handler) |
||||
mtlr r6 |
||||
blrl |
||||
.L_Alignment: |
||||
.long AlignmentException - _start + EXC_OFF_SYS_RESET |
||||
.long int_return - _start + EXC_OFF_SYS_RESET |
||||
|
||||
/* Program check exception */ |
||||
. = 0x700 |
||||
ProgramCheck: |
||||
EXCEPTION_PROLOG(SRR0, SRR1) |
||||
addi r3,r1,STACK_FRAME_OVERHEAD |
||||
li r20,MSR_KERNEL |
||||
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ |
||||
rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */ |
||||
lwz r6,GOT(transfer_to_handler) |
||||
mtlr r6 |
||||
blrl |
||||
.L_ProgramCheck: |
||||
.long ProgramCheckException - _start + EXC_OFF_SYS_RESET |
||||
.long int_return - _start + EXC_OFF_SYS_RESET |
||||
|
||||
/* Floating Point Unit unavailable exception */ |
||||
STD_EXCEPTION(0x800, FPUnavailable, UnknownException) |
||||
|
||||
/* Decrementer */ |
||||
STD_EXCEPTION(0x900, Decrementer, timer_interrupt) |
||||
|
||||
/* Critical interrupt */ |
||||
STD_EXCEPTION(0xa00, Critical, UnknownException) |
||||
|
||||
/* System Call */ |
||||
STD_EXCEPTION(0xc00, SystemCall, UnknownException) |
||||
|
||||
/* Trace interrupt */ |
||||
STD_EXCEPTION(0xd00, Trace, UnknownException) |
||||
|
||||
/* Performance Monitor interrupt */ |
||||
STD_EXCEPTION(0xf00, PerfMon, UnknownException) |
||||
|
||||
/* Intruction Translation Miss */ |
||||
STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException) |
||||
|
||||
/* Data Load Translation Miss */ |
||||
STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException) |
||||
|
||||
/* Data Store Translation Miss */ |
||||
STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException) |
||||
|
||||
/* Instruction Address Breakpoint */ |
||||
STD_EXCEPTION(0x1300, InstructionAddrBreakpoint, DebugException) |
||||
|
||||
/* System Management interrupt */ |
||||
STD_EXCEPTION(0x1400, SystemMgmtInterrupt, UnknownException) |
||||
|
||||
.globl _end_of_vectors
|
||||
_end_of_vectors: |
||||
|
||||
. = 0x3000 |
||||
boot_cold: |
||||
/* Save msr contents */ |
||||
mfmsr r5 |
||||
|
||||
/* Set IMMR area to our preferred location */ |
||||
lis r4, CONFIG_DEFAULT_IMMR@h
|
||||
lis r3, CFG_IMMR@h
|
||||
ori r3, r3, CFG_IMMR@l
|
||||
stw r3, IMMRBAR(r4) |
||||
mtspr MBAR, r3 /* IMMRBAR is mirrored into the MBAR SPR (311) */ |
||||
|
||||
/* Initialise the machine */ |
||||
bl cpu_early_init |
||||
|
||||
/* |
||||
* Set up Local Access Windows: |
||||
* |
||||
* 1) Boot/CS0 (boot FLASH) |
||||
* 2) On-chip SRAM (initial stack purposes) |
||||
*/ |
||||
|
||||
/* Boot CS/CS0 window range */ |
||||
lis r3, CFG_IMMR@h
|
||||
ori r3, r3, CFG_IMMR@l
|
||||
|
||||
lis r4, START_REG(CFG_FLASH_BASE) |
||||
ori r4, r4, STOP_REG(CFG_FLASH_BASE, CFG_FLASH_SIZE) |
||||
stw r4, LPCS0AW(r3) |
||||
|
||||
/* |
||||
* The SRAM window has a fixed size (256K), so only the start address |
||||
* is necessary |
||||
*/ |
||||
lis r4, START_REG(CFG_SRAM_BASE) & 0xff00 |
||||
stw r4, SRAMBAR(r3) |
||||
|
||||
/*
|
||||
* According to MPC5121e RM, configuring local access windows should |
||||
* be followed by a dummy read of the config register that was |
||||
* modified last and an isync |
||||
*/ |
||||
lwz r4, SRAMBAR(r3) |
||||
isync |
||||
|
||||
/* |
||||
* Set configuration of the Boot/CS0, the SRAM window does not have a |
||||
* config register so no params can be set for it |
||||
*/ |
||||
lis r3, (CFG_IMMR + LPC_OFFSET)@h
|
||||
ori r3, r3, (CFG_IMMR + LPC_OFFSET)@l
|
||||
|
||||
lis r4, CFG_CS0_CFG@h
|
||||
ori r4, r4, CFG_CS0_CFG@l
|
||||
stw r4, CS0_CONFIG(r3) |
||||
|
||||
/* Master enable all CS's */ |
||||
lis r4, CS_CTRL_ME@h
|
||||
ori r4, r4, CS_CTRL_ME@l
|
||||
stw r4, CS_CTRL(r3) |
||||
|
||||
lis r4, (CFG_MONITOR_BASE)@h
|
||||
ori r4, r4, (CFG_MONITOR_BASE)@l
|
||||
addi r5, r4, in_flash - _start + EXC_OFF_SYS_RESET |
||||
mtlr r5 |
||||
blr |
||||
|
||||
in_flash: |
||||
lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
|
||||
ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
|
||||
|
||||
li r0, 0 /* Make room for stack frame header and */ |
||||
stwu r0, -4(r1) /* clear final stack frame so that */ |
||||
stwu r0, -4(r1) /* stack backtraces terminate cleanly */ |
||||
|
||||
/* let the C-code set up the rest */ |
||||
/* */ |
||||
/* Be careful to keep code relocatable & stack humble */ |
||||
/*------------------------------------------------------*/ |
||||
|
||||
GET_GOT /* initialize GOT access */ |
||||
|
||||
/* r3: IMMR */ |
||||
lis r3, CFG_IMMR@h
|
||||
/* run low-level CPU init code (in Flash) */ |
||||
bl cpu_init_f |
||||
|
||||
/* r3: BOOTFLAG */ |
||||
mr r3, r21 |
||||
/* run 1st part of board init code (in Flash) */ |
||||
bl board_init_f |
||||
|
||||
/* NOTREACHED - board_init_f() does not return */ |
||||
|
||||
/* |
||||
* This code finishes saving the registers to the exception frame |
||||
* and jumps to the appropriate handler for the exception. |
||||
* Register r21 is pointer into trap frame, r1 has new stack pointer. |
||||
*/ |
||||
.globl transfer_to_handler
|
||||
transfer_to_handler: |
||||
stw r22,_NIP(r21) |
||||
lis r22,MSR_POW@h
|
||||
andc r23,r23,r22 |
||||
stw r23,_MSR(r21) |
||||
SAVE_GPR(7, r21) |
||||
SAVE_4GPRS(8, r21) |
||||
SAVE_8GPRS(12, r21) |
||||
SAVE_8GPRS(24, r21) |
||||
mflr r23 |
||||
andi. r24,r23,0x3f00 /* get vector offset */ |
||||
stw r24,TRAP(r21) |
||||
li r22,0 |
||||
stw r22,RESULT(r21) |
||||
lwz r24,0(r23) /* virtual address of handler */ |
||||
lwz r23,4(r23) /* where to go when done */ |
||||
mtspr SRR0,r24 |
||||
mtspr SRR1,r20 |
||||
mtlr r23 |
||||
SYNC |
||||
rfi /* jump to handler, enable MMU */ |
||||
|
||||
int_return: |
||||
mfmsr r28 /* Disable interrupts */ |
||||
li r4,0 |
||||
ori r4,r4,MSR_EE |
||||
andc r28,r28,r4 |
||||
SYNC /* Some chip revs need this... */ |
||||
mtmsr r28 |
||||
SYNC |
||||
lwz r2,_CTR(r1) |
||||
lwz r0,_LINK(r1) |
||||
mtctr r2 |
||||
mtlr r0 |
||||
lwz r2,_XER(r1) |
||||
lwz r0,_CCR(r1) |
||||
mtspr XER,r2 |
||||
mtcrf 0xFF,r0 |
||||
REST_10GPRS(3, r1) |
||||
REST_10GPRS(13, r1) |
||||
REST_8GPRS(23, r1) |
||||
REST_GPR(31, r1) |
||||
lwz r2,_NIP(r1) /* Restore environment */ |
||||
lwz r0,_MSR(r1) |
||||
mtspr SRR0,r2 |
||||
mtspr SRR1,r0 |
||||
lwz r0,GPR0(r1) |
||||
lwz r2,GPR2(r1) |
||||
lwz r1,GPR1(r1) |
||||
SYNC |
||||
rfi |
||||
|
||||
/* |
||||
* This code initialises the machine, it expects original MSR contents to be in r5. |
||||
*/ |
||||
cpu_early_init: |
||||
/* Initialize machine status; enable machine check interrupt */ |
||||
/*-----------------------------------------------------------*/ |
||||
|
||||
li r3, MSR_KERNEL /* Set ME and RI flags */ |
||||
rlwimi r3, r5, 0, 25, 25 /* preserve IP bit */ |
||||
#ifdef DEBUG |
||||
rlwimi r3, r5, 0, 21, 22 /* debugger might set SE, BE bits */ |
||||
#endif |
||||
mtmsr r3 |
||||
SYNC |
||||
mtspr SRR1, r3 /* Mirror current MSR state in SRR1 */ |
||||
|
||||
lis r3, CFG_IMMR@h
|
||||
|
||||
#if defined(CONFIG_WATCHDOG) |
||||
/* Initialise the watchdog and reset it */ |
||||
/*--------------------------------------*/ |
||||
lis r4, CFG_WATCHDOG_VALUE |
||||
ori r4, r4, (SWCRR_SWEN | SWCRR_SWRI | SWCRR_SWPR) |
||||
stw r4, SWCRR(r3) |
||||
|
||||
/* reset */ |
||||
li r4, 0x556C |
||||
sth r4, SWSRR@l(r3)
|
||||
li r4, 0x0 |
||||
ori r4, r4, 0xAA39 |
||||
sth r4, SWSRR@l(r3)
|
||||
#else |
||||
/* Disable the watchdog */ |
||||
/*----------------------*/ |
||||
lwz r4, SWCRR(r3) |
||||
/* |
||||
* Check to see if it's enabled for disabling: once disabled by s/w |
||||
* it's not possible to re-enable it |
||||
*/ |
||||
andi. r4, r4, 0x4 |
||||
beq 1f |
||||
xor r4, r4, r4 |
||||
stw r4, SWCRR(r3) |
||||
1: |
||||
#endif /* CONFIG_WATCHDOG */ |
||||
|
||||
/* Initialize the Hardware Implementation-dependent Registers */ |
||||
/* HID0 also contains cache control */ |
||||
/*------------------------------------------------------*/ |
||||
lis r3, CFG_HID0_INIT@h
|
||||
ori r3, r3, CFG_HID0_INIT@l
|
||||
SYNC |
||||
mtspr HID0, r3 |
||||
|
||||
lis r3, CFG_HID0_FINAL@h
|
||||
ori r3, r3, CFG_HID0_FINAL@l
|
||||
SYNC |
||||
mtspr HID0, r3 |
||||
|
||||
lis r3, CFG_HID2@h
|
||||
ori r3, r3, CFG_HID2@l
|
||||
SYNC |
||||
mtspr HID2, r3 |
||||
sync |
||||
blr |
||||
|
||||
|
||||
/* Cache functions. |
||||
* |
||||
* Note: requires that all cache bits in |
||||
* HID0 are in the low half word. |
||||
*/ |
||||
.globl icache_enable
|
||||
icache_enable: |
||||
mfspr r3, HID0 |
||||
ori r3, r3, HID0_ICE |
||||
lis r4, 0 |
||||
ori r4, r4, HID0_ILOCK |
||||
andc r3, r3, r4 |
||||
ori r4, r3, HID0_ICFI |
||||
isync |
||||
mtspr HID0, r4 /* sets enable and invalidate, clears lock */ |
||||
isync |
||||
mtspr HID0, r3 /* clears invalidate */ |
||||
blr |
||||
|
||||
.globl icache_disable
|
||||
icache_disable: |
||||
mfspr r3, HID0 |
||||
lis r4, 0 |
||||
ori r4, r4, HID0_ICE|HID0_ILOCK |
||||
andc r3, r3, r4 |
||||
ori r4, r3, HID0_ICFI |
||||
isync |
||||
mtspr HID0, r4 /* sets invalidate, clears enable and lock*/ |
||||
isync |
||||
mtspr HID0, r3 /* clears invalidate */ |
||||
blr |
||||
|
||||
.globl icache_status
|
||||
icache_status: |
||||
mfspr r3, HID0 |
||||
rlwinm r3, r3, (31 - HID0_ICE_SHIFT + 1), 31, 31 |
||||
blr |
||||
|
||||
.globl dcache_enable
|
||||
dcache_enable: |
||||
mfspr r3, HID0 |
||||
li r5, HID0_DCFI|HID0_DLOCK |
||||
andc r3, r3, r5 |
||||
mtspr HID0, r3 /* no invalidate, unlock */ |
||||
ori r3, r3, HID0_DCE |
||||
ori r5, r3, HID0_DCFI |
||||
mtspr HID0, r5 /* enable + invalidate */ |
||||
mtspr HID0, r3 /* enable */ |
||||
sync |
||||
blr |
||||
|
||||
.globl dcache_disable
|
||||
dcache_disable: |
||||
mfspr r3, HID0 |
||||
lis r4, 0 |
||||
ori r4, r4, HID0_DCE|HID0_DLOCK |
||||
andc r3, r3, r4 |
||||
ori r4, r3, HID0_DCI |
||||
sync |
||||
mtspr HID0, r4 /* sets invalidate, clears enable and lock */ |
||||
sync |
||||
mtspr HID0, r3 /* clears invalidate */ |
||||
blr |
||||
|
||||
.globl dcache_status
|
||||
dcache_status: |
||||
mfspr r3, HID0 |
||||
rlwinm r3, r3, (31 - HID0_DCE_SHIFT + 1), 31, 31 |
||||
blr |
||||
|
||||
.globl get_pvr
|
||||
get_pvr: |
||||
mfspr r3, PVR |
||||
blr |
||||
|
||||
/*------------------------------------------------------------------------------- */ |
||||
/* Function: ppcDcbf */ |
||||
/* Description: Data Cache block flush */ |
||||
/* Input: r3 = effective address */ |
||||
/* Output: none. */ |
||||
/*------------------------------------------------------------------------------- */ |
||||
.globl ppcDcbf
|
||||
ppcDcbf: |
||||
dcbf r0,r3 |
||||
blr |
||||
|
||||
/*------------------------------------------------------------------------------- */ |
||||
/* Function: ppcDcbi */ |
||||
/* Description: Data Cache block Invalidate */ |
||||
/* Input: r3 = effective address */ |
||||
/* Output: none. */ |
||||
/*------------------------------------------------------------------------------- */ |
||||
.globl ppcDcbi
|
||||
ppcDcbi: |
||||
dcbi r0,r3 |
||||
blr |
||||
|
||||
/*-------------------------------------------------------------------------- |
||||
* Function: ppcDcbz |
||||
* Description: Data Cache block zero. |
||||
* Input: r3 = effective address |
||||
* Output: none. |
||||
*-------------------------------------------------------------------------- */ |
||||
|
||||
.globl ppcDcbz
|
||||
ppcDcbz: |
||||
dcbz r0,r3 |
||||
blr |
||||
|
||||
.globl ppcDWstore
|
||||
ppcDWstore: |
||||
lfd 1, 0(r4) |
||||
stfd 1, 0(r3) |
||||
blr |
||||
|
||||
.globl ppcDWload
|
||||
ppcDWload: |
||||
lfd 1, 0(r3) |
||||
stfd 1, 0(r4) |
||||
blr |
||||
|
||||
/*-------------------------------------------------------------------*/ |
||||
|
||||
/* |
||||
* void relocate_code (addr_sp, gd, addr_moni) |
||||
* |
||||
* This "function" does not return, instead it continues in RAM |
||||
* after relocating the monitor code. |
||||
* |
||||
* r3 = dest |
||||
* r4 = src |
||||
* r5 = length in bytes |
||||
* r6 = cachelinesize |
||||
*/ |
||||
.globl relocate_code
|
||||
relocate_code: |
||||
mr r1, r3 /* Set new stack pointer */ |
||||
mr r9, r4 /* Save copy of Global Data pointer */ |
||||
mr r10, r5 /* Save copy of Destination Address */ |
||||
|
||||
mr r3, r5 /* Destination Address */ |
||||
lis r4, CFG_MONITOR_BASE@h /* Source Address */
|
||||
ori r4, r4, CFG_MONITOR_BASE@l
|
||||
lwz r5, GOT(__init_end) |
||||
sub r5, r5, r4 |
||||
li r6, CFG_CACHELINE_SIZE /* Cache Line Size */ |
||||
|
||||
/* |
||||
* Fix GOT pointer: |
||||
* |
||||
* New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) |
||||
* + Destination Address |
||||
* |
||||
* Offset: |
||||
*/ |
||||
sub r15, r10, r4 |
||||
|
||||
/* First our own GOT */ |
||||
add r14, r14, r15 |
||||
/* then the one used by the C code */ |
||||
add r30, r30, r15 |
||||
|
||||
/* |
||||
* Now relocate code |
||||
*/ |
||||
cmplw cr1,r3,r4 |
||||
addi r0,r5,3 |
||||
srwi. r0,r0,2 |
||||
beq cr1,4f /* In place copy is not necessary */ |
||||
beq 7f /* Protect against 0 count */ |
||||
mtctr r0 |
||||
bge cr1,2f |
||||
la r8,-4(r4) |
||||
la r7,-4(r3) |
||||
|
||||
/* copy */ |
||||
1: lwzu r0,4(r8) |
||||
stwu r0,4(r7) |
||||
bdnz 1b |
||||
|
||||
addi r0,r5,3 |
||||
srwi. r0,r0,2 |
||||
mtctr r0 |
||||
la r8,-4(r4) |
||||
la r7,-4(r3) |
||||
|
||||
/* and compare */ |
||||
20: lwzu r20,4(r8) |
||||
lwzu r21,4(r7) |
||||
xor. r22, r20, r21 |
||||
bne 30f |
||||
bdnz 20b |
||||
b 4f |
||||
|
||||
/* compare failed */ |
||||
30: li r3, 0 |
||||
blr |
||||
|
||||
2: slwi r0,r0,2 /* re copy in reverse order ... y do we needed it? */ |
||||
add r8,r4,r0 |
||||
add r7,r3,r0 |
||||
3: lwzu r0,-4(r8) |
||||
stwu r0,-4(r7) |
||||
bdnz 3b |
||||
|
||||
/* |
||||
* Now flush the cache: note that we must start from a cache aligned |
||||
* address. Otherwise we might miss one cache line. |
||||
*/ |
||||
4: cmpwi r6,0 |
||||
add r5,r3,r5 |
||||
beq 7f /* Always flush prefetch queue in any case */ |
||||
subi r0,r6,1 |
||||
andc r3,r3,r0 |
||||
mr r4,r3 |
||||
5: dcbst 0,r4 |
||||
add r4,r4,r6 |
||||
cmplw r4,r5 |
||||
blt 5b |
||||
sync /* Wait for all dcbst to complete on bus */ |
||||
mr r4,r3 |
||||
6: icbi 0,r4 |
||||
add r4,r4,r6 |
||||
cmplw r4,r5 |
||||
blt 6b |
||||
7: sync /* Wait for all icbi to complete on bus */ |
||||
isync |
||||
|
||||
/* |
||||
* We are done. Do not return, instead branch to second part of board |
||||
* initialization, now running from RAM. |
||||
*/ |
||||
addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET |
||||
mtlr r0 |
||||
blr |
||||
|
||||
in_ram: |
||||
/* |
||||
* Relocation Function, r14 point to got2+0x8000 |
||||
* |
||||
* Adjust got2 pointers, no need to check for 0, this code |
||||
* already puts a few entries in the table. |
||||
*/ |
||||
li r0,__got2_entries@sectoff@l
|
||||
la r3,GOT(_GOT2_TABLE_) |
||||
lwz r11,GOT(_GOT2_TABLE_) |
||||
mtctr r0 |
||||
sub r11,r3,r11 |
||||
addi r3,r3,-4 |
||||
1: lwzu r0,4(r3) |
||||
add r0,r0,r11 |
||||
stw r0,0(r3) |
||||
bdnz 1b |
||||
|
||||
/* |
||||
* Now adjust the fixups and the pointers to the fixups |
||||
* in case we need to move ourselves again. |
||||
*/ |
||||
2: li r0,__fixup_entries@sectoff@l
|
||||
lwz r3,GOT(_FIXUP_TABLE_) |
||||
cmpwi r0,0 |
||||
mtctr r0 |
||||
addi r3,r3,-4 |
||||
beq 4f |
||||
3: lwzu r4,4(r3) |
||||
lwzux r0,r4,r11 |
||||
add r0,r0,r11 |
||||
stw r10,0(r3) |
||||
stw r0,0(r4) |
||||
bdnz 3b |
||||
4: |
||||
clear_bss: |
||||
/* |
||||
* Now clear BSS segment |
||||
*/ |
||||
lwz r3,GOT(__bss_start) |
||||
lwz r4,GOT(_end) |
||||
|
||||
cmplw 0, r3, r4 |
||||
beq 6f |
||||
|
||||
li r0, 0 |
||||
5: |
||||
stw r0, 0(r3) |
||||
addi r3, r3, 4 |
||||
cmplw 0, r3, r4 |
||||
bne 5b |
||||
6: |
||||
mr r3, r9 /* Global Data pointer */ |
||||
mr r4, r10 /* Destination Address */ |
||||
bl board_init_r |
||||
|
||||
/* |
||||
* Copy exception vector code to low memory |
||||
* |
||||
* r3: dest_addr |
||||
* r7: source address, r8: end address, r9: target address |
||||
*/ |
||||
.globl trap_init
|
||||
trap_init: |
||||
lwz r7, GOT(_start) |
||||
lwz r8, GOT(_end_of_vectors) |
||||
|
||||
li r9, 0x100 /* reset vector at 0x100 */ |
||||
|
||||
cmplw 0, r7, r8 |
||||
bgelr /* return if r7>=r8 - just in case */ |
||||
|
||||
mflr r4 /* save link register */ |
||||
1: |
||||
lwz r0, 0(r7) |
||||
stw r0, 0(r9) |
||||
addi r7, r7, 4 |
||||
addi r9, r9, 4 |
||||
cmplw 0, r7, r8 |
||||
bne 1b |
||||
|
||||
/* |
||||
* relocate `hdlr' and `int_return' entries |
||||
*/ |
||||
li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET |
||||
li r8, Alignment - _start + EXC_OFF_SYS_RESET |
||||
2: |
||||
bl trap_reloc |
||||
addi r7, r7, 0x100 /* next exception vector */ |
||||
cmplw 0, r7, r8 |
||||
blt 2b |
||||
|
||||
li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET |
||||
bl trap_reloc |
||||
|
||||
li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET |
||||
bl trap_reloc |
||||
|
||||
li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET |
||||
li r8, SystemCall - _start + EXC_OFF_SYS_RESET |
||||
3: |
||||
bl trap_reloc |
||||
addi r7, r7, 0x100 /* next exception vector */ |
||||
cmplw 0, r7, r8 |
||||
blt 3b |
||||
|
||||
li r7, .L_Trace - _start + EXC_OFF_SYS_RESET |
||||
li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET |
||||
4: |
||||
bl trap_reloc |
||||
addi r7, r7, 0x100 /* next exception vector */ |
||||
cmplw 0, r7, r8 |
||||
blt 4b |
||||
|
||||
mfmsr r3 /* now that the vectors have */ |
||||
lis r7, MSR_IP@h /* relocated into low memory */
|
||||
ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
|
||||
andc r3, r3, r7 /* (if it was on) */ |
||||
SYNC /* Some chip revs need this... */ |
||||
mtmsr r3 |
||||
SYNC |
||||
|
||||
mtlr r4 /* restore link register */ |
||||
blr |
||||
|
||||
/* |
||||
* Function: relocate entries for one exception vector |
||||
*/ |
||||
trap_reloc: |
||||
lwz r0, 0(r7) /* hdlr ... */ |
||||
add r0, r0, r3 /* ... += dest_addr */ |
||||
stw r0, 0(r7) |
||||
|
||||
lwz r0, 4(r7) /* int_return ... */ |
||||
add r0, r0, r3 /* ... += dest_addr */ |
||||
stw r0, 4(r7) |
||||
|
||||
blr |
@ -0,0 +1,205 @@ |
||||
/*
|
||||
* (C) Copyright 2000 - 2007 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
* Derived from the MPC83xx code. |
||||
*/ |
||||
|
||||
/*
|
||||
* This file handles the architecture-dependent parts of hardware |
||||
* exceptions |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/processor.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
extern unsigned long search_exception_table(unsigned long); |
||||
|
||||
#define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize) |
||||
|
||||
/*
|
||||
* Trap & Exception support |
||||
*/ |
||||
|
||||
void |
||||
print_backtrace (unsigned long *sp) |
||||
{ |
||||
int cnt = 0; |
||||
unsigned long i; |
||||
|
||||
puts ("Call backtrace: "); |
||||
while (sp) { |
||||
if ((uint)sp > END_OF_MEM) |
||||
break; |
||||
|
||||
i = sp[1]; |
||||
if (cnt++ % 7 == 0) |
||||
putc ('\n'); |
||||
printf ("%08lX ", i); |
||||
if (cnt > 32) break; |
||||
sp = (unsigned long *) *sp; |
||||
} |
||||
putc ('\n'); |
||||
} |
||||
|
||||
void show_regs (struct pt_regs * regs) |
||||
{ |
||||
int i; |
||||
|
||||
printf ("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %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); |
||||
|
||||
putc ('\n'); |
||||
for (i = 0; i < 32; i++) { |
||||
if ((i % 8) == 0) { |
||||
printf ("GPR%02d: ", i); |
||||
} |
||||
|
||||
printf ("%08lX ", regs->gpr[i]); |
||||
if ((i % 8) == 7) { |
||||
putc ('\n'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
void |
||||
_exception (int signr, struct pt_regs *regs) |
||||
{ |
||||
show_regs (regs); |
||||
print_backtrace ((unsigned long *)regs->gpr[1]); |
||||
panic ("Exception at pc %lx signal %d", regs->nip,signr); |
||||
} |
||||
|
||||
|
||||
void |
||||
MachineCheckException (struct pt_regs *regs) |
||||
{ |
||||
unsigned long fixup; |
||||
|
||||
if ((fixup = search_exception_table (regs->nip)) != 0) { |
||||
regs->nip = fixup; |
||||
return; |
||||
} |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
if (debugger_exception_handler && (*debugger_exception_handler)(regs)) |
||||
return; |
||||
#endif |
||||
|
||||
puts ("Machine check.\nCaused by (from msr): "); |
||||
printf ("regs %p ",regs); |
||||
switch (regs->msr & 0x00FF0000) { |
||||
case (0x80000000 >> 10): |
||||
puts ("Instruction cache parity signal\n"); |
||||
break; |
||||
case (0x80000000 >> 11): |
||||
puts ("Data cache parity signal\n"); |
||||
break; |
||||
case (0x80000000 >> 12): |
||||
puts ("Machine check signal\n"); |
||||
break; |
||||
case (0x80000000 >> 13): |
||||
puts ("Transfer error ack signal\n"); |
||||
break; |
||||
case (0x80000000 >> 14): |
||||
puts ("Data parity signal\n"); |
||||
break; |
||||
case (0x80000000 >> 15): |
||||
puts ("Address parity signal\n"); |
||||
break; |
||||
default: |
||||
puts ("Unknown values in msr\n"); |
||||
} |
||||
show_regs (regs); |
||||
print_backtrace ((unsigned long *)regs->gpr[1]); |
||||
|
||||
panic ("machine check"); |
||||
} |
||||
|
||||
void |
||||
AlignmentException (struct pt_regs *regs) |
||||
{ |
||||
#if (CONFIG_COMMANDS & CFG_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) |
||||
{ |
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
if (debugger_exception_handler && (*debugger_exception_handler)(regs)) |
||||
return; |
||||
#endif |
||||
show_regs (regs); |
||||
print_backtrace ((unsigned long *)regs->gpr[1]); |
||||
panic ("Program Check Exception"); |
||||
} |
||||
|
||||
void |
||||
SoftEmuException (struct pt_regs *regs) |
||||
{ |
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
if (debugger_exception_handler && (*debugger_exception_handler)(regs)) |
||||
return; |
||||
#endif |
||||
show_regs (regs); |
||||
print_backtrace ((unsigned long *)regs->gpr[1]); |
||||
panic ("Software Emulation Exception"); |
||||
} |
||||
|
||||
|
||||
void |
||||
UnknownException (struct pt_regs *regs) |
||||
{ |
||||
#if (CONFIG_COMMANDS & CFG_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); |
||||
} |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) |
||||
extern void do_bedbug_breakpoint (struct pt_regs *); |
||||
#endif |
||||
|
||||
void |
||||
DebugException (struct pt_regs *regs) |
||||
{ |
||||
printf ("Debugger trap at @ %lx\n", regs->nip ); |
||||
show_regs (regs); |
||||
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) |
||||
do_bedbug_breakpoint (regs); |
||||
#endif |
||||
} |
@ -0,0 +1,569 @@ |
||||
/*
|
||||
* (C) Copyright 2007 DENX Software Engineering |
||||
* |
||||
* MPC512x Internal Memory Map |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
* |
||||
* Based on the MPC83xx header. |
||||
*/ |
||||
|
||||
#ifndef __IMMAP_512x__ |
||||
#define __IMMAP_512x__ |
||||
|
||||
#include <asm/types.h> |
||||
|
||||
typedef struct law512x { |
||||
u32 bar; /* Base Addr Register */ |
||||
u32 ar; /* Attributes Register */ |
||||
} law521x_t; |
||||
|
||||
/*
|
||||
* System configuration registers |
||||
*/ |
||||
typedef struct sysconf512x { |
||||
u32 immrbar; /* Internal memory map base address register */ |
||||
u8 res0[0x1c]; |
||||
u32 lpbaw; /* LP Boot Access Window */ |
||||
u32 lpcs0aw; /* LP CS0 Access Window */ |
||||
u32 lpcs1aw; /* LP CS1 Access Window */ |
||||
u32 lpcs2aw; /* LP CS2 Access Window */ |
||||
u32 lpcs3aw; /* LP CS3 Access Window */ |
||||
u32 lpcs4aw; /* LP CS4 Access Window */ |
||||
u32 lpcs5aw; /* LP CS5 Access Window */ |
||||
u32 lpcs6aw; /* LP CS6 Access Window */ |
||||
u32 lpcs7aw; /* LP CS7 Access Window */ |
||||
u8 res1[0x1c]; |
||||
law521x_t pcilaw[3]; /* PCI Local Access Window 0-2 Registers */ |
||||
u8 res2[0x28]; |
||||
law521x_t ddrlaw; /* DDR Local Access Window */ |
||||
u8 res3[0x18]; |
||||
u32 mbxbar; /* MBX Base Address */ |
||||
u32 srambar; /* SRAM Base Address */ |
||||
u32 nfcbar; /* NFC Base Address */ |
||||
u8 res4[0x34]; |
||||
u32 spridr; /* System Part and Revision ID Register */ |
||||
u32 spcr; /* System Priority Configuration Register */ |
||||
u8 res5[0xf8]; |
||||
} sysconf512x_t; |
||||
|
||||
/*
|
||||
* Watch Dog Timer (WDT) Registers |
||||
*/ |
||||
typedef struct wdt512x { |
||||
u8 res0[4]; |
||||
u32 swcrr; /* System watchdog control register */ |
||||
u32 swcnr; /* System watchdog count register */ |
||||
u8 res1[2]; |
||||
u16 swsrr; /* System watchdog service register */ |
||||
u8 res2[0xF0]; |
||||
} wdt512x_t; |
||||
|
||||
/*
|
||||
* RTC Module Registers |
||||
*/ |
||||
typedef struct rtclk512x { |
||||
u8 fixme[0x100]; |
||||
} rtclk512x_t; |
||||
|
||||
/*
|
||||
* General Purpose Timer |
||||
*/ |
||||
typedef struct gpt512x { |
||||
u8 fixme[0x100]; |
||||
} gpt512x_t; |
||||
|
||||
/*
|
||||
* Integrated Programmable Interrupt Controller |
||||
*/ |
||||
typedef struct ipic512x { |
||||
u8 fixme[0x100]; |
||||
} ipic512x_t; |
||||
|
||||
/*
|
||||
* System Arbiter Registers |
||||
*/ |
||||
typedef struct arbiter512x { |
||||
u32 acr; /* Arbiter Configuration Register */ |
||||
u32 atr; /* Arbiter Timers Register */ |
||||
u32 ater; /* Arbiter Transfer Error Register */ |
||||
u32 aer; /* Arbiter Event Register */ |
||||
u32 aidr; /* Arbiter Interrupt Definition Register */ |
||||
u32 amr; /* Arbiter Mask Register */ |
||||
u32 aeatr; /* Arbiter Event Attributes Register */ |
||||
u32 aeadr; /* Arbiter Event Address Register */ |
||||
u32 aerr; /* Arbiter Event Response Register */ |
||||
u8 res1[0xDC]; |
||||
} arbiter512x_t; |
||||
|
||||
/*
|
||||
* Reset Module |
||||
*/ |
||||
typedef struct reset512x { |
||||
u32 rcwl; /* Reset Configuration Word Low Register */ |
||||
u32 rcwh; /* Reset Configuration Word High Register */ |
||||
u8 res0[8]; |
||||
u32 rsr; /* Reset Status Register */ |
||||
u32 rmr; /* Reset Mode Register */ |
||||
u32 rpr; /* Reset protection Register */ |
||||
u32 rcr; /* Reset Control Register */ |
||||
u32 rcer; /* Reset Control Enable Register */ |
||||
u8 res1[0xDC]; |
||||
} reset512x_t; |
||||
|
||||
/*
|
||||
* Clock Module |
||||
*/ |
||||
typedef struct clk512x { |
||||
u32 spmr; /* System PLL Mode Register */ |
||||
u32 sccr[2]; /* System Clock Control Registers */ |
||||
u32 scfr[2]; /* System Clock Frequency Registers */ |
||||
u8 res0[4]; |
||||
u32 bcr; /* Bread Crumb Register */ |
||||
u32 pscccr[12]; /* PSC0-11 Clock Control Registers */ |
||||
u32 spccr; /* SPDIF Clock Control Registers */ |
||||
u32 cccr; /* CFM Clock Control Registers */ |
||||
u32 dccr; /* DIU Clock Control Registers */ |
||||
u8 res1[0xa8]; |
||||
} clk512x_t; |
||||
|
||||
/*
|
||||
* Power Management Control Module |
||||
*/ |
||||
typedef struct pmc512x { |
||||
u8 fixme[0x100]; |
||||
} pmc512x_t; |
||||
|
||||
/*
|
||||
* General purpose I/O module |
||||
*/ |
||||
typedef struct gpio512x { |
||||
u8 fixme[0x100]; |
||||
} gpio512x_t; |
||||
|
||||
/*
|
||||
* DDR Memory Controller Memory Map |
||||
*/ |
||||
typedef struct ddr512x { |
||||
u32 ddr_sys_config; /* System Configuration Register */ |
||||
u32 ddr_time_config0; /* Timing Configuration Register */ |
||||
u32 ddr_time_config1; /* Timing Configuration Register */ |
||||
u32 ddr_time_config2; /* Timing Configuration Register */ |
||||
u32 ddr_command; /* Command Register */ |
||||
u32 ddr_compact_command; /* Compact Command Register */ |
||||
u32 self_refresh_cmd_0; /* Enter/Exit Self Refresh Registers */ |
||||
u32 self_refresh_cmd_1; /* Enter/Exit Self Refresh Registers */ |
||||
u32 self_refresh_cmd_2; /* Enter/Exit Self Refresh Registers */ |
||||
u32 self_refresh_cmd_3; /* Enter/Exit Self Refresh Registers */ |
||||
u32 self_refresh_cmd_4; /* Enter/Exit Self Refresh Registers */ |
||||
u32 self_refresh_cmd_5; /* Enter/Exit Self Refresh Registers */ |
||||
u32 self_refresh_cmd_6; /* Enter/Exit Self Refresh Registers */ |
||||
u32 self_refresh_cmd_7; /* Enter/Exit Self Refresh Registers */ |
||||
u32 DQS_config_offset_count; /* DQS Config Offset Count */ |
||||
u32 DQS_config_offset_time; /* DQS Config Offset Time */ |
||||
u32 DQS_delay_status; /* DQS Delay Status */ |
||||
u32 res0[0xF]; |
||||
u32 prioman_config1; /* Priority Manager Configuration */ |
||||
u32 prioman_config2; /* Priority Manager Configuration */ |
||||
u32 hiprio_config; /* High Priority Configuration */ |
||||
u32 lut_table0_main_upper; /* LUT0 Main Upper */ |
||||
u32 lut_table1_main_upper; /* LUT1 Main Upper */ |
||||
u32 lut_table2_main_upper; /* LUT2 Main Upper */ |
||||
u32 lut_table3_main_upper; /* LUT3 Main Upper */ |
||||
u32 lut_table4_main_upper; /* LUT4 Main Upper */ |
||||
u32 lut_table0_main_lower; /* LUT0 Main Lower */ |
||||
u32 lut_table1_main_lower; /* LUT1 Main Lower */ |
||||
u32 lut_table2_main_lower; /* LUT2 Main Lower */ |
||||
u32 lut_table3_main_lower; /* LUT3 Main Lower */ |
||||
u32 lut_table4_main_lower; /* LUT4 Main Lower */ |
||||
u32 lut_table0_alternate_upper; /* LUT0 Alternate Upper */ |
||||
u32 lut_table1_alternate_upper; /* LUT1 Alternate Upper */ |
||||
u32 lut_table2_alternate_upper; /* LUT2 Alternate Upper */ |
||||
u32 lut_table3_alternate_upper; /* LUT3 Alternate Upper */ |
||||
u32 lut_table4_alternate_upper; /* LUT4 Alternate Upper */ |
||||
u32 lut_table0_alternate_lower; /* LUT0 Alternate Lower */ |
||||
u32 lut_table1_alternate_lower; /* LUT1 Alternate Lower */ |
||||
u32 lut_table2_alternate_lower; /* LUT2 Alternate Lower */ |
||||
u32 lut_table3_alternate_lower; /* LUT3 Alternate Lower */ |
||||
u32 lut_table4_alternate_lower; /* LUT4 Alternate Lower */ |
||||
u32 performance_monitor_config; |
||||
u32 event_time_counter; |
||||
u32 event_time_preset; |
||||
u32 performance_monitor1_address_low; |
||||
u32 performance_monitor2_address_low; |
||||
u32 performance_monitor1_address_hi; |
||||
u32 performance_monitor2_address_hi; |
||||
u32 res1[2]; |
||||
u32 performance_monitor1_read_counter; |
||||
u32 performance_monitor2_read_counter; |
||||
u32 performance_monitor1_write_counter; |
||||
u32 performance_monitor2_write_counter; |
||||
u32 granted_ack_counter0; |
||||
u32 granted_ack_counter1; |
||||
u32 granted_ack_counter2; |
||||
u32 granted_ack_counter3; |
||||
u32 granted_ack_counter4; |
||||
u32 cumulative_wait_counter0; |
||||
u32 cumulative_wait_counter1; |
||||
u32 cumulative_wait_counter2; |
||||
u32 cumulative_wait_counter3; |
||||
u32 cumulative_wait_counter4; |
||||
u32 summed_priority_counter0; |
||||
u32 summed_priority_counter1; |
||||
u32 summed_priority_counter2; |
||||
u32 summed_priority_counter3; |
||||
u32 summed_priority_counter4; |
||||
u32 res2[0x3AD]; |
||||
} ddr512x_t; |
||||
|
||||
|
||||
/*
|
||||
* DMA/Messaging Unit |
||||
*/ |
||||
typedef struct dma512x { |
||||
u8 fixme[0x1800]; |
||||
} dma512x_t; |
||||
|
||||
/*
|
||||
* PCI Software Configuration Registers |
||||
*/ |
||||
typedef struct pciconf512x { |
||||
u8 fixme[0x80]; |
||||
} pciconf512x_t; |
||||
|
||||
/*
|
||||
* Sequencer |
||||
*/ |
||||
typedef struct ios512x { |
||||
u8 fixme[0x100]; |
||||
} ios512x_t; |
||||
|
||||
/*
|
||||
* PCI Controller |
||||
*/ |
||||
typedef struct pcictrl512x { |
||||
u8 fixme[0x100]; |
||||
} pcictrl512x_t; |
||||
|
||||
|
||||
/*
|
||||
* MSCAN |
||||
*/ |
||||
typedef struct mscan512x { |
||||
u8 fixme[0x100]; |
||||
} mscan512x_t; |
||||
|
||||
/*
|
||||
* BDLC |
||||
*/ |
||||
typedef struct bdlc512x { |
||||
u8 fixme[0x100]; |
||||
} bdlc512x_t; |
||||
|
||||
/*
|
||||
* SDHC |
||||
*/ |
||||
typedef struct sdhc512x { |
||||
u8 fixme[0x100]; |
||||
} sdhc512x_t; |
||||
|
||||
/*
|
||||
* SPDIF |
||||
*/ |
||||
typedef struct spdif512x { |
||||
u8 fixme[0x100]; |
||||
} spdif512x_t; |
||||
|
||||
/*
|
||||
* I2C |
||||
*/ |
||||
typedef struct i2c512x_dev { |
||||
volatile u32 madr; /* I2Cn + 0x00 */ |
||||
volatile u32 mfdr; /* I2Cn + 0x04 */ |
||||
volatile u32 mcr; /* I2Cn + 0x08 */ |
||||
volatile u32 msr; /* I2Cn + 0x0C */ |
||||
volatile u32 mdr; /* I2Cn + 0x10 */ |
||||
u8 res0[0x0C]; |
||||
} i2c512x_dev_t; |
||||
|
||||
typedef struct i2c512x { |
||||
i2c512x_dev_t dev[3]; |
||||
volatile u32 icr; |
||||
volatile u32 mifr; |
||||
u8 res0[0x98]; |
||||
} i2c512x_t; |
||||
|
||||
/*
|
||||
* AXE |
||||
*/ |
||||
typedef struct axe512x { |
||||
u8 fixme[0x100]; |
||||
} axe512x_t; |
||||
|
||||
/*
|
||||
* DIU |
||||
*/ |
||||
typedef struct diu512x { |
||||
u8 fixme[0x100]; |
||||
} diu512x_t; |
||||
|
||||
/*
|
||||
* CFM |
||||
*/ |
||||
typedef struct cfm512x { |
||||
u8 fixme[0x100]; |
||||
} cfm512x_t; |
||||
|
||||
/*
|
||||
* FEC |
||||
*/ |
||||
typedef struct fec512x { |
||||
u8 fixme[0x800]; |
||||
} fec512x_t; |
||||
|
||||
/*
|
||||
* ULPI |
||||
*/ |
||||
typedef struct ulpi512x { |
||||
u8 fixme[0x600]; |
||||
} ulpi512x_t; |
||||
|
||||
/*
|
||||
* UTMI |
||||
*/ |
||||
typedef struct utmi512x { |
||||
u8 fixme[0x3000]; |
||||
} utmi512x_t; |
||||
|
||||
/*
|
||||
* PCI DMA |
||||
*/ |
||||
typedef struct pcidma512x { |
||||
u8 fixme[0x300]; |
||||
} pcidma512x_t; |
||||
|
||||
/*
|
||||
* IO Control |
||||
*/ |
||||
typedef struct ioctrl512x { |
||||
u32 regs[0x400]; |
||||
} ioctrl512x_t; |
||||
|
||||
/*
|
||||
* IIM |
||||
*/ |
||||
typedef struct iim512x { |
||||
u8 fixme[0x1000]; |
||||
} iim512x_t; |
||||
|
||||
/*
|
||||
* LPC |
||||
*/ |
||||
typedef struct lpc512x { |
||||
u32 cs_cfg[8]; /* Chip Select N Configuration Registers
|
||||
No dedicated entry for CS Boot as == CS0 */ |
||||
u32 cs_cr; /* Chip Select Control Register */ |
||||
u32 cs_sr; /* Chip Select Status Register */ |
||||
u32 cs_bcr; /* Chip Select Burst Control Register */ |
||||
u32 cs_dccr; /* Chip Select Deadcycle Control Register */ |
||||
u32 cs_hccr; /* Chip Select Holdcycle Control Register */ |
||||
u8 res0[0xcc]; |
||||
u32 sclpc_psr; /* SCLPC Packet Size Register */ |
||||
u32 sclpc_sar; /* SCLPC Start Address Register */ |
||||
u32 sclpc_cr; /* SCLPC Control Register */ |
||||
u32 sclpc_er; /* SCLPC Enable Register */ |
||||
u32 sclpc_nar; /* SCLPC NextAddress Register */ |
||||
u32 sclpc_sr; /* SCLPC Status Register */ |
||||
u32 sclpc_bdr; /* SCLPC Bytes Done Register */ |
||||
u32 emb_scr; /* EMB Share Counter Register */ |
||||
u32 emb_pcr; /* EMB Pause Control Register */ |
||||
u8 res1[0x1c]; |
||||
u32 lpc_fdwr; /* LPC RX/TX FIFO Data Word Register */ |
||||
u32 lpc_fsr; /* LPC RX/TX FIFO Status Register */ |
||||
u32 lpc_cr; /* LPC RX/TX FIFO Control Register */ |
||||
u32 lpc_ar; /* LPC RX/TX FIFO Alarm Register */ |
||||
u8 res2[0xb0]; |
||||
} lpc512x_t; |
||||
|
||||
/*
|
||||
* PATA |
||||
*/ |
||||
typedef struct pata512x { |
||||
u8 fixme[0x100]; |
||||
} pata512x_t; |
||||
|
||||
/*
|
||||
* PSC |
||||
*/ |
||||
typedef struct psc512x { |
||||
volatile u8 mode; /* PSC + 0x00 */ |
||||
volatile u8 res0[3]; |
||||
union { /* PSC + 0x04 */ |
||||
volatile u16 status; |
||||
volatile u16 clock_select; |
||||
} sr_csr; |
||||
#define psc_status sr_csr.status |
||||
#define psc_clock_select sr_csr.clock_select |
||||
volatile u16 res1; |
||||
volatile u8 command; /* PSC + 0x08 */ |
||||
volatile u8 res2[3]; |
||||
union { /* PSC + 0x0c */ |
||||
volatile u8 buffer_8; |
||||
volatile u16 buffer_16; |
||||
volatile u32 buffer_32; |
||||
} buffer; |
||||
#define psc_buffer_8 buffer.buffer_8 |
||||
#define psc_buffer_16 buffer.buffer_16 |
||||
#define psc_buffer_32 buffer.buffer_32 |
||||
union { /* PSC + 0x10 */ |
||||
volatile u8 ipcr; |
||||
volatile u8 acr; |
||||
} ipcr_acr; |
||||
#define psc_ipcr ipcr_acr.ipcr |
||||
#define psc_acr ipcr_acr.acr |
||||
volatile u8 res3[3]; |
||||
union { /* PSC + 0x14 */ |
||||
volatile u16 isr; |
||||
volatile u16 imr; |
||||
} isr_imr; |
||||
#define psc_isr isr_imr.isr |
||||
#define psc_imr isr_imr.imr |
||||
volatile u16 res4; |
||||
volatile u8 ctur; /* PSC + 0x18 */ |
||||
volatile u8 res5[3]; |
||||
volatile u8 ctlr; /* PSC + 0x1c */ |
||||
volatile u8 res6[3]; |
||||
volatile u32 ccr; /* PSC + 0x20 */ |
||||
volatile u8 res7[12]; |
||||
volatile u8 ivr; /* PSC + 0x30 */ |
||||
volatile u8 res8[3]; |
||||
volatile u8 ip; /* PSC + 0x34 */ |
||||
volatile u8 res9[3]; |
||||
volatile u8 op1; /* PSC + 0x38 */ |
||||
volatile u8 res10[3]; |
||||
volatile u8 op0; /* PSC + 0x3c */ |
||||
volatile u8 res11[3]; |
||||
volatile u32 sicr; /* PSC + 0x40 */ |
||||
volatile u8 res12[60]; |
||||
volatile u32 tfcmd; /* PSC + 0x80 */ |
||||
volatile u32 tfalarm; /* PSC + 0x84 */ |
||||
volatile u32 tfstat; /* PSC + 0x88 */ |
||||
volatile u32 tfintstat; /* PSC + 0x8C */ |
||||
volatile u32 tfintmask; /* PSC + 0x90 */ |
||||
volatile u32 tfcount; /* PSC + 0x94 */ |
||||
volatile u16 tfwptr; /* PSC + 0x98 */ |
||||
volatile u16 tfrptr; /* PSC + 0x9A */ |
||||
volatile u32 tfsize; /* PSC + 0x9C */ |
||||
volatile u8 res13[28]; |
||||
union { /* PSC + 0xBC */ |
||||
volatile u8 buffer_8; |
||||
volatile u16 buffer_16; |
||||
volatile u32 buffer_32; |
||||
} tfdata_buffer; |
||||
#define tfdata_8 tfdata_buffer.buffer_8 |
||||
#define tfdata_16 tfdata_buffer.buffer_16 |
||||
#define tfdata_32 tfdata_buffer.buffer_32 |
||||
|
||||
volatile u32 rfcmd; /* PSC + 0xC0 */ |
||||
volatile u32 rfalarm; /* PSC + 0xC4 */ |
||||
volatile u32 rfstat; /* PSC + 0xC8 */ |
||||
volatile u32 rfintstat; /* PSC + 0xCC */ |
||||
volatile u32 rfintmask; /* PSC + 0xD0 */ |
||||
volatile u32 rfcount; /* PSC + 0xD4 */ |
||||
volatile u16 rfwptr; /* PSC + 0xD8 */ |
||||
volatile u16 rfrptr; /* PSC + 0xDA */ |
||||
volatile u32 rfsize; /* PSC + 0xDC */ |
||||
volatile u8 res18[28]; |
||||
union { /* PSC + 0xFC */ |
||||
volatile u8 buffer_8; |
||||
volatile u16 buffer_16; |
||||
volatile u32 buffer_32; |
||||
} rfdata_buffer; |
||||
#define rfdata_8 rfdata_buffer.buffer_8 |
||||
#define rfdata_16 rfdata_buffer.buffer_16 |
||||
#define rfdata_32 rfdata_buffer.buffer_32 |
||||
} psc512x_t; |
||||
|
||||
/*
|
||||
* FIFOC |
||||
*/ |
||||
typedef struct fifoc512x { |
||||
u32 fifoc_cmd; |
||||
u32 fifoc_int; |
||||
u32 fifoc_dma; |
||||
u32 fifoc_axe; |
||||
u32 fifoc_debug; |
||||
u8 fixme[0xEC]; |
||||
} fifoc512x_t; |
||||
|
||||
/*
|
||||
* SATA |
||||
*/ |
||||
typedef struct sata512x { |
||||
u8 fixme[0x2000]; |
||||
} sata512x_t; |
||||
|
||||
typedef struct immap { |
||||
sysconf512x_t sysconf; /* System configuration */ |
||||
u8 res0[0x700]; |
||||
wdt512x_t wdt; /* Watch Dog Timer (WDT) */ |
||||
rtclk512x_t rtc; /* Real Time Clock Module */ |
||||
gpt512x_t gpt; /* General Purpose Timer */ |
||||
ipic512x_t ipic; /* Integrated Programmable Interrupt Controller */ |
||||
arbiter512x_t arbiter; /* CSB Arbiter */ |
||||
reset512x_t reset; /* Reset Module */ |
||||
clk512x_t clk; /* Clock Module */ |
||||
pmc512x_t pmc; /* Power Management Control Module */ |
||||
gpio512x_t gpio; /* General purpose I/O module */ |
||||
u8 res1[0x100]; |
||||
mscan512x_t mscan; /* MSCAN */ |
||||
bdlc512x_t bdlc; /* BDLC */ |
||||
sdhc512x_t sdhc; /* SDHC */ |
||||
spdif512x_t spdif; /* SPDIF */ |
||||
i2c512x_t i2c; /* I2C Controllers */ |
||||
u8 res2[0x800]; |
||||
axe512x_t axe; /* AXE */ |
||||
diu512x_t diu; /* Display Interface Unit */ |
||||
cfm512x_t cfm; /* Clock Frequency Measurement */ |
||||
u8 res3[0x500]; |
||||
fec512x_t fec; /* Fast Ethernet Controller */ |
||||
ulpi512x_t ulpi; /* USB ULPI */ |
||||
u8 res4[0xa00]; |
||||
utmi512x_t utmi; /* USB UTMI */ |
||||
u8 res5[0x1000]; |
||||
pcidma512x_t pci_dma; /* PCI DMA */ |
||||
pciconf512x_t pci_conf; /* PCI Configuration */ |
||||
u8 res6[0x80]; |
||||
ios512x_t ios; /* PCI Sequencer */ |
||||
pcictrl512x_t pci_ctrl; /* PCI Controller Control and Status */ |
||||
u8 res7[0xa00]; |
||||
ddr512x_t mddrc; /* Multi-port DDR Memory Controller */ |
||||
ioctrl512x_t io_ctrl; /* IO Control */ |
||||
iim512x_t iim; /* IC Identification module */ |
||||
u8 res8[0x4000]; |
||||
lpc512x_t lpc; /* LocalPlus Controller */ |
||||
pata512x_t pata; /* Parallel ATA */ |
||||
u8 res9[0xd00]; |
||||
psc512x_t psc[12]; /* PSCs */ |
||||
u8 res10[0x300]; |
||||
fifoc512x_t fifoc; /* FIFO Controller */ |
||||
u8 res11[0x2000]; |
||||
dma512x_t dma; /* DMA */ |
||||
u8 res12[0xa800]; |
||||
sata512x_t sata; /* Serial ATA */ |
||||
u8 res13[0xde000]; |
||||
} immap_t; |
||||
#endif /* __IMMAP_512x__ */ |
@ -0,0 +1,410 @@ |
||||
/*
|
||||
* (C) Copyright 2007 DENX Software Engineering |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
/*
|
||||
* ADS5121 board configuration file |
||||
*/ |
||||
|
||||
#ifndef __CONFIG_H |
||||
#define __CONFIG_H |
||||
|
||||
#define DEBUG |
||||
#undef DEBUG |
||||
|
||||
/*
|
||||
* Memory map for the ADS5121 board: |
||||
* |
||||
* 0x0000_0000 - 0x0FFF_FFFF DDR RAM (256 MB) |
||||
* 0x3000_0000 - 0x3001_FFFF SRAM (128 KB) |
||||
* 0x8000_0000 - 0x803F_FFFF IMMR (4 MB) |
||||
* 0x8200_0000 - 0x8200_001F CPLD (32 B) |
||||
* 0xFC00_0000 - 0xFFFF_FFFF NOR Boot FLASH (64 MB) |
||||
*/ |
||||
|
||||
/*
|
||||
* High Level Configuration Options |
||||
*/ |
||||
#define CONFIG_E300 1 /* E300 Family */ |
||||
#define CONFIG_MPC512X 1 /* MPC512X family */ |
||||
|
||||
#undef CONFIG_PCI |
||||
|
||||
#define CFG_MPC512X_CLKIN 66000000 /* in Hz */ |
||||
|
||||
#define CONFIG_BOARD_EARLY_INIT_F /* call board_early_init_f() */ |
||||
|
||||
#define CFG_IMMR 0x80000000 |
||||
|
||||
#define CFG_MEMTEST_START 0x00200000 /* memtest region */ |
||||
#define CFG_MEMTEST_END 0x00400000 |
||||
|
||||
/*
|
||||
* DDR Setup - manually set all parameters as there's no SPD etc. |
||||
*/ |
||||
#define CFG_DDR_SIZE 256 /* MB */ |
||||
#define CFG_DDR_BASE 0x00000000 /* DDR is system memory*/ |
||||
#define CFG_SDRAM_BASE CFG_DDR_BASE |
||||
|
||||
/* DDR Controller Configuration
|
||||
|
||||
SYS_CFG: |
||||
[31:31] MDDRC Soft Reset: Diabled |
||||
[30:30] DRAM CKE pin: Enabled |
||||
[29:29] DRAM CLK: Enabled |
||||
[28:28] Command Mode: Enabled (For initialization only)
|
||||
[27:25] DRAM Row Select: dram_row[15:0] = magenta_address[25:10] |
||||
[24:21] DRAM Bank Select: dram_bank[1:0] = magenta_address[11:10] |
||||
[20:19] Read Test: DON'T USE |
||||
[18:18] Self Refresh: Enabled |
||||
[17:17] 16bit Mode: Disabled |
||||
[16:13] Ready Delay: 2 |
||||
[12:12] Half DQS Delay: Disabled |
||||
[11:11] Quarter DQS Delay: Disabled |
||||
[10:08] Write Delay: 2 |
||||
[07:07] Early ODT: Disabled |
||||
[06:06] On DIE Termination: Disabled |
||||
[05:05] FIFO Overflow Clear: DON'T USE here |
||||
[04:04] FIFO Underflow Clear: DON'T USE here |
||||
[03:03] FIFO Overflow Pending: DON'T USE here |
||||
[02:02] FIFO Underlfow Pending: DON'T USE here |
||||
[01:01] FIFO Overlfow Enabled: Enabled |
||||
[00:00] FIFO Underflow Enabled: Enabled |
||||
TIME_CFG0 |
||||
[31:16] DRAM Refresh Time: 0 CSB clocks
|
||||
[15:8] DRAM Command Time: 0 CSB clocks |
||||
[07:00] DRAM Precharge Time: 0 CSB clocks |
||||
TIME_CFG1 |
||||
[31:26] DRAM tRFC: |
||||
[25:21] DRAM tWR1: |
||||
[20:17] DRAM tWRT1: |
||||
[16:11] DRAM tDRR: |
||||
[10:05] DRAM tRC: |
||||
[04:00] DRAM tRAS: |
||||
TIME_CFG2 |
||||
[31:28] DRAM tRCD: |
||||
[27:23] DRAM tFAW: |
||||
[22:19] DRAM tRTW1: |
||||
[18:15] DRAM tCCD: |
||||
[14:10] DRAM tRTP: |
||||
[09:05] DRAM tRP: |
||||
[04:00] DRAM tRPA */ |
||||
|
||||
#define CFG_MDDRC_SYS_CFG 0xF8604200 |
||||
#define CFG_MDDRC_SYS_CFG_RUN 0xE8604200 |
||||
#define CFG_MDDRC_SYS_CFG_EN 0x30000000 |
||||
#define CFG_MDDRC_TIME_CFG0 0x0000281E |
||||
#define CFG_MDDRC_TIME_CFG0_RUN 0x01F4281E |
||||
#define CFG_MDDRC_TIME_CFG1 0x54EC1168 |
||||
#define CFG_MDDRC_TIME_CFG2 0x35210864 |
||||
|
||||
#define CFG_MICRON_NOP 0x01380000 |
||||
#define CFG_MICRON_PCHG_ALL 0x01100400 |
||||
#define CFG_MICRON_MR 0x01000022 |
||||
#define CFG_MICRON_EM2 0x01020000 |
||||
#define CFG_MICRON_EM3 0x01030000 |
||||
#define CFG_MICRON_EN_DLL 0x01010000 |
||||
#define CFG_MICRON_RST_DLL 0x01000932 |
||||
#define CFG_MICRON_RFSH 0x01080000 |
||||
#define CFG_MICRON_INIT_DEV_OP 0x01000832 |
||||
#define CFG_MICRON_OCD_DEFAULT 0x01010780 |
||||
#define CFG_MICRON_OCD_EXIT 0x01010400 |
||||
|
||||
/* DDR Priority Manager Configuration */ |
||||
#define CFG_MDDRCGRP_PM_CFG1 0x000777AA |
||||
#define CFG_MDDRCGRP_PM_CFG2 0x00000055 |
||||
#define CFG_MDDRCGRP_HIPRIO_CFG 0x00000000 |
||||
#define CFG_MDDRCGRP_LUT0_MU 0x11111117 |
||||
#define CFG_MDDRCGRP_LUT0_ML 0x7777777A |
||||
#define CFG_MDDRCGRP_LUT1_MU 0x4444EEEE |
||||
#define CFG_MDDRCGRP_LUT1_ML 0xEEEEEEEE |
||||
#define CFG_MDDRCGRP_LUT2_MU 0x44444444 |
||||
#define CFG_MDDRCGRP_LUT2_ML 0x44444444 |
||||
#define CFG_MDDRCGRP_LUT3_MU 0x55555555 |
||||
#define CFG_MDDRCGRP_LUT3_ML 0x55555558 |
||||
#define CFG_MDDRCGRP_LUT4_MU 0x11111111 |
||||
#define CFG_MDDRCGRP_LUT4_ML 0x1111117C |
||||
#define CFG_MDDRCGRP_LUT0_AU 0x33333377 |
||||
#define CFG_MDDRCGRP_LUT0_AL 0x7777EEEE |
||||
#define CFG_MDDRCGRP_LUT1_AU 0x11111111 |
||||
#define CFG_MDDRCGRP_LUT1_AL 0x11111111 |
||||
#define CFG_MDDRCGRP_LUT2_AU 0x11111111 |
||||
#define CFG_MDDRCGRP_LUT2_AL 0x11111111 |
||||
#define CFG_MDDRCGRP_LUT3_AU 0x11111111 |
||||
#define CFG_MDDRCGRP_LUT3_AL 0x11111111 |
||||
#define CFG_MDDRCGRP_LUT4_AU 0x11111111 |
||||
#define CFG_MDDRCGRP_LUT4_AL 0x11111111 |
||||
|
||||
/*
|
||||
* NOR FLASH on the Local Bus |
||||
*/ |
||||
#define CFG_FLASH_CFI /* use the Common Flash Interface */ |
||||
#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ |
||||
#define CFG_FLASH_BASE 0xFC000000 /* start of FLASH */ |
||||
#define CFG_FLASH_SIZE 0x04000000 /* max flash size in bytes */ |
||||
#define CFG_FLASH_USE_BUFFER_WRITE |
||||
|
||||
#define CFG_MAX_FLASH_BANKS 1 /* number of banks */ |
||||
#define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE} |
||||
#define CFG_MAX_FLASH_SECT 256 /* max sectors per device */ |
||||
|
||||
#undef CFG_FLASH_CHECKSUM |
||||
|
||||
/*
|
||||
* CPLD registers area is really only 32 bytes in size, but the smallest possible LP |
||||
* window is 64KB |
||||
*/ |
||||
#define CFG_CPLD_BASE 0x82000000 |
||||
#define CFG_CPLD_SIZE 0x00010000 /* 64 KB */ |
||||
|
||||
#define CFG_SRAM_BASE 0x30000000 |
||||
#define CFG_SRAM_SIZE 0x00020000 /* 128 KB */ |
||||
|
||||
#define CFG_CS0_CFG 0x05059310 /* ALE active low, data size 4bytes */ |
||||
#define CFG_CS2_CFG 0x05059010 /* ALE active low, data size 1byte */ |
||||
|
||||
/* Use SRAM for initial stack */ |
||||
#define CFG_INIT_RAM_ADDR CFG_SRAM_BASE /* Initial RAM address */ |
||||
#define CFG_INIT_RAM_END CFG_SRAM_SIZE /* End of used area in RAM */ |
||||
|
||||
#define CFG_GBL_DATA_SIZE 0x100 /* num bytes initial data */ |
||||
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) |
||||
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET |
||||
|
||||
#define CFG_MONITOR_BASE TEXT_BASE /* Start of monitor */ |
||||
#define CFG_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Mon */ |
||||
#define CFG_MALLOC_LEN (512 * 1024) /* Reserved for malloc */ |
||||
|
||||
/*
|
||||
* Serial Port |
||||
*/ |
||||
#define CONFIG_CONS_INDEX 1 |
||||
#undef CONFIG_SERIAL_SOFTWARE_FIFO |
||||
|
||||
/*
|
||||
* Serial console configuration |
||||
*/ |
||||
#define CONFIG_PSC_CONSOLE 3 /* console is on PSC3 */ |
||||
#if CONFIG_PSC_CONSOLE != 3 |
||||
#error CONFIG_PSC_CONSOLE must be 3 |
||||
#endif |
||||
#define CONFIG_BAUDRATE 115200 /* ... at 115200 bps */ |
||||
#define CFG_BAUDRATE_TABLE \ |
||||
{300, 600, 1200, 2400, 4800, 9600, 19200, 38400,115200} |
||||
|
||||
#define CONSOLE_FIFO_TX_SIZE FIFOC_PSC3_TX_SIZE |
||||
#define CONSOLE_FIFO_TX_ADDR FIFOC_PSC3_TX_ADDR |
||||
#define CONSOLE_FIFO_RX_SIZE FIFOC_PSC3_RX_SIZE |
||||
#define CONSOLE_FIFO_RX_ADDR FIFOC_PSC3_RX_ADDR |
||||
|
||||
#define CONFIG_CMDLINE_EDITING 1 /* add command line history */ |
||||
/* Use the HUSH parser */ |
||||
#define CFG_HUSH_PARSER |
||||
#ifdef CFG_HUSH_PARSER |
||||
#define CFG_PROMPT_HUSH_PS2 "> " |
||||
#endif |
||||
|
||||
/* I2C */ |
||||
#define CONFIG_HARD_I2C /* I2C with hardware support */ |
||||
#undef CONFIG_SOFT_I2C /* so disable bit-banged I2C */ |
||||
#define CONFIG_I2C_MULTI_BUS |
||||
#define CONFIG_I2C_CMD_TREE |
||||
#define CFG_I2C_SPEED 100000 /* I2C speed and slave address */ |
||||
#define CFG_I2C_SLAVE 0x7F |
||||
#if 0 |
||||
#define CFG_I2C_NOPROBES {{0,0x69}} * Don't probe these addrs */ |
||||
#endif |
||||
|
||||
/*
|
||||
* Ethernet configuration |
||||
*/ |
||||
#define CONFIG_MPC512x_FEC 1 |
||||
#define CONFIG_NET_MULTI |
||||
#define CONFIG_PHY_ADDR 0x1 |
||||
#define CONFIG_MII 1 /* MII PHY management */ |
||||
#define CONFIG_ETHADDR 00:e0:5e:00:e5:14 |
||||
|
||||
#if 0 |
||||
/*
|
||||
* Configure on-board RTC |
||||
*/ |
||||
#define CONFIG_RTC_DS1374 /* use ds1374 rtc via i2c */ |
||||
#define CFG_I2C_RTC_ADDR 0x68 /* at address 0x68 */ |
||||
#endif |
||||
|
||||
/*
|
||||
* Environment |
||||
*/ |
||||
#define CFG_ENV_IS_IN_FLASH 1 |
||||
/* This has to be a multiple of the Flash sector size */ |
||||
#define CFG_ENV_ADDR (CFG_MONITOR_BASE + CFG_MONITOR_LEN) |
||||
#define CFG_ENV_SIZE 0x2000 |
||||
#define CFG_ENV_SECT_SIZE 0x40000 /* one sector (256K) for env */ |
||||
|
||||
/* Address and size of Redundant Environment Sector */ |
||||
#define CFG_ENV_ADDR_REDUND (CFG_ENV_ADDR + CFG_ENV_SECT_SIZE) |
||||
#define CFG_ENV_SIZE_REDUND (CFG_ENV_SIZE) |
||||
|
||||
#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ |
||||
#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ |
||||
|
||||
#if defined(CONFIG_PCI) |
||||
#define CONFIG_COMMANDS (CONFIG_CMD_DFL \ |
||||
| CFG_CMD_PCI \
|
||||
| CFG_CMD_NET \
|
||||
| CFG_CMD_PING \
|
||||
) |
||||
#else |
||||
#define CONFIG_COMMANDS (CONFIG_CMD_DFL \ |
||||
| CFG_CMD_NET \
|
||||
| CFG_CMD_PING \
|
||||
| CFG_CMD_MII \
|
||||
| CFG_CMD_I2C) |
||||
#endif |
||||
|
||||
#include <cmd_confdefs.h> |
||||
|
||||
/*
|
||||
* Watchdog timeout = CFG_WATCHDOG_VALUE * 65536 / IPS clock. |
||||
* For example, when IPS is set to 66MHz and CFG_WATCHDOG_VALUE is set |
||||
* to 0xFFFF, watchdog timeouts after about 64s. For details refer |
||||
* to chapter 36 of the MPC5121e Reference Manual. |
||||
*/ |
||||
#define CONFIG_WATCHDOG /* enable watchdog */ |
||||
#define CFG_WATCHDOG_VALUE 0xFFFF |
||||
|
||||
/*
|
||||
* Miscellaneous configurable options |
||||
*/ |
||||
#define CFG_LONGHELP /* undef to save memory */ |
||||
#define CFG_LOAD_ADDR 0x2000000 /* default load address */ |
||||
#define CFG_PROMPT "=> " /* Monitor Command Prompt */ |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ |
||||
#else |
||||
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ |
||||
#endif |
||||
|
||||
|
||||
#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) /* Print Buffer Size */ |
||||
#define CFG_MAXARGS 16 /* max number of command args */ |
||||
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ |
||||
#define CFG_HZ 1000 /* decrementer freq: 1ms ticks */ |
||||
|
||||
/*
|
||||
* For booting Linux, the board info and command line data |
||||
* have to be in the first 8 MB of memory, since this is |
||||
* the maximum mapped by the Linux kernel during initialization. |
||||
*/ |
||||
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux*/ |
||||
|
||||
/* Cache Configuration */ |
||||
#define CFG_DCACHE_SIZE 32768 |
||||
#define CFG_CACHELINE_SIZE 32 |
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
#define CFG_CACHELINE_SHIFT 5 /*log base 2 of the above value*/ |
||||
#endif |
||||
|
||||
#define CFG_HID0_INIT 0x000000000 |
||||
#define CFG_HID0_FINAL HID0_ENABLE_MACHINE_CHECK |
||||
#define CFG_HID2 HID2_HBE |
||||
|
||||
/*
|
||||
* Internal Definitions |
||||
* |
||||
* Boot Flags |
||||
*/ |
||||
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ |
||||
#define BOOTFLAG_WARM 0x02 /* Software reboot */ |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
#define CONFIG_KGDB_BAUDRATE 230400 /* speed of kgdb serial port */ |
||||
#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ |
||||
#endif |
||||
|
||||
/*
|
||||
* Environment Configuration |
||||
*/ |
||||
#define CONFIG_ENV_OVERWRITE |
||||
|
||||
#define CONFIG_HOSTNAME ads5121 |
||||
#define CONFIG_ROOTPATH /nfsroot/rootfs |
||||
#define CONFIG_BOOTFILE uImage |
||||
|
||||
#define CONFIG_IPADDR 192.168.160.77 |
||||
#define CONFIG_SERVERIP 192.168.1.1 |
||||
#define CONFIG_GATEWAYIP 192.168.1.1 |
||||
#define CONFIG_NETMASK 255.255.0.0 |
||||
|
||||
#define CONFIG_LOADADDR 200000 /* default location for tftp and bootm */ |
||||
|
||||
//#define CONFIG_BOOTDELAY 6 /* -1 disables auto-boot */
|
||||
#define CONFIG_BOOTDELAY -1 |
||||
#undef CONFIG_BOOTARGS /* the boot command will set bootargs */ |
||||
|
||||
#define CONFIG_BAUDRATE 115200 |
||||
|
||||
#define CONFIG_PREBOOT "echo;" \ |
||||
"echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \
|
||||
"echo" |
||||
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \ |
||||
"netdev=eth0\0" \
|
||||
"nfsargs=setenv bootargs root=/dev/nfs rw " \
|
||||
"nfsroot=${serverip}:${rootpath}\0" \
|
||||
"ramargs=setenv bootargs root=/dev/ram rw\0" \
|
||||
"addip=setenv bootargs ${bootargs} " \
|
||||
"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \
|
||||
":${hostname}:${netdev}:off panic=1\0" \
|
||||
"addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}\0"\
|
||||
"flash_nfs=run nfsargs addip addtty;" \
|
||||
"bootm ${kernel_addr}\0" \
|
||||
"flash_self=run ramargs addip addtty;" \
|
||||
"bootm ${kernel_addr} ${ramdisk_addr}\0" \
|
||||
"net_nfs=tftp 200000 ${bootfile};run nfsargs addip addtty;" \
|
||||
"bootm\0" \
|
||||
"load=tftp 100000 /tftpboot/ads5121/u-boot.bin\0" \
|
||||
"update=protect off fff00000 fff3ffff; " \
|
||||
"era fff00000 fff3ffff; cp.b 100000 fff00000 ${filesize}\0" \
|
||||
"upd=run load;run update\0" \
|
||||
"" |
||||
|
||||
#define CONFIG_NFSBOOTCOMMAND \ |
||||
"setenv bootargs root=/dev/nfs rw " \
|
||||
"nfsroot=$serverip:$rootpath " \
|
||||
"ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \
|
||||
"console=$consoledev,$baudrate $othbootargs;" \
|
||||
"tftp $loadaddr $bootfile;" \
|
||||
"tftp $fdtaddr $fdtfile;" \
|
||||
"bootm $loadaddr - $fdtaddr" |
||||
|
||||
#define CONFIG_RAMBOOTCOMMAND \ |
||||
"setenv bootargs root=/dev/ram rw " \
|
||||
"console=$consoledev,$baudrate $othbootargs;" \
|
||||
"tftp $ramdiskaddr $ramdiskfile;" \
|
||||
"tftp $loadaddr $bootfile;" \
|
||||
"tftp $fdtaddr $fdtfile;" \
|
||||
"bootm $loadaddr $ramdiskaddr $fdtaddr" |
||||
|
||||
#define CONFIG_BOOTCOMMAND "run flash_self" |
||||
|
||||
#endif /* __CONFIG_H */ |
@ -0,0 +1,398 @@ |
||||
/*
|
||||
* Copyright (C) 2004-2006 Freescale Semiconductor, Inc. |
||||
* (C) Copyright 2007 DENX Software Engineering |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License as |
||||
* published by the Free Software Foundation; either version 2 of |
||||
* the License, or (at your option) any later version. |
||||
* |
||||
* Derived from the MPC83xx header. |
||||
*/ |
||||
|
||||
#ifndef __MPC512X_H__ |
||||
#define __MPC512X_H__ |
||||
|
||||
#include <config.h> |
||||
#if defined(CONFIG_E300) |
||||
#include <asm/e300.h> |
||||
#endif |
||||
|
||||
/* System reset offset (PowerPC standard)
|
||||
*/ |
||||
#define EXC_OFF_SYS_RESET 0x0100 |
||||
#define _START_OFFSET EXC_OFF_SYS_RESET |
||||
|
||||
|
||||
/* IMMRBAR - Internal Memory Register Base Address
|
||||
*/ |
||||
#define CONFIG_DEFAULT_IMMR 0xFF400000 /* Default IMMR base address */ |
||||
#define IMMRBAR 0x0000 /* Register offset to immr */ |
||||
#define IMMRBAR_BASE_ADDR 0xFFF00000 /* Base address mask */ |
||||
#define IMMRBAR_RES ~(IMMRBAR_BASE_ADDR) |
||||
|
||||
/* LAWBAR - Local Access Window Base Address Register
|
||||
*/ |
||||
#define LPBAW 0x0020 /* Register offset to immr */ |
||||
#define LPCS0AW 0x0024 |
||||
#define LPCS1AW 0x0028 |
||||
#define LPCS2AW 0x002C |
||||
#define LPCS3AW 0x0030 |
||||
#define LPCS4AW 0x0034 |
||||
#define LPCS5AW 0x0038 |
||||
#define LPCS6AW 0x003C |
||||
#define LPCA7AW 0x0040 |
||||
#define SRAMBAR 0x00C4 |
||||
|
||||
#define LPC_OFFSET 0x10000 |
||||
|
||||
#define CS0_CONFIG 0x00000 |
||||
#define CS1_CONFIG 0x00004 |
||||
#define CS2_CONFIG 0x00008 |
||||
#define CS3_CONFIG 0x0000C |
||||
#define CS4_CONFIG 0x00010 |
||||
#define CS5_CONFIG 0x00014 |
||||
#define CS6_CONFIG 0x00018 |
||||
#define CS7_CONFIG 0x0001C |
||||
|
||||
#define CS_CTRL 0x00020 |
||||
#define CS_CTRL_ME 0x01000000 /* CS Master Enable bit */ |
||||
#define CS_CTRL_IE 0x08000000 /* CS Interrupt Enable bit */ |
||||
|
||||
/* SPRIDR - System Part and Revision ID Register
|
||||
*/ |
||||
#define SPRIDR_PARTID 0xFFFF0000 /* Part Identification */ |
||||
#define SPRIDR_REVID 0x0000FFFF /* Revision Identification */ |
||||
|
||||
#define SPR_5121E 0x80180000 |
||||
|
||||
/* SPCR - System Priority Configuration Register
|
||||
*/ |
||||
#define SPCR_PCIHPE 0x10000000 /* PCI Highest Priority Enable */ |
||||
#define SPCR_PCIHPE_SHIFT (31-3) |
||||
#define SPCR_PCIPR 0x03000000 /* PCI bridge system bus request priority */ |
||||
#define SPCR_PCIPR_SHIFT (31-7) |
||||
#define SPCR_TBEN 0x00400000 /* E300 PowerPC core time base unit enable */ |
||||
#define SPCR_TBEN_SHIFT (31-9) |
||||
#define SPCR_COREPR 0x00300000 /* E300 PowerPC Core system bus request priority */ |
||||
#define SPCR_COREPR_SHIFT (31-11) |
||||
|
||||
/* SWCRR - System Watchdog Control Register
|
||||
*/ |
||||
#define SWCRR 0x0904 /* Register offset to immr */ |
||||
#define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count */ |
||||
#define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit */ |
||||
#define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit */ |
||||
#define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit */ |
||||
#define SWCRR_RES ~(SWCRR_SWTC | SWCRR_SWEN | SWCRR_SWRI | SWCRR_SWPR) |
||||
|
||||
/* SWCNR - System Watchdog Counter Register
|
||||
*/ |
||||
#define SWCNR 0x0908 /* Register offset to immr */ |
||||
#define SWCNR_SWCN 0x0000FFFF /* Software Watchdog Count mask */ |
||||
#define SWCNR_RES ~(SWCNR_SWCN) |
||||
|
||||
/* SWSRR - System Watchdog Service Register
|
||||
*/ |
||||
#define SWSRR 0x090E /* Register offset to immr */ |
||||
|
||||
/* ACR - Arbiter Configuration Register
|
||||
*/ |
||||
#define ACR_COREDIS 0x10000000 /* Core disable */ |
||||
#define ACR_COREDIS_SHIFT (31-7) |
||||
#define ACR_PIPE_DEP 0x00070000 /* Pipeline depth */ |
||||
#define ACR_PIPE_DEP_SHIFT (31-15) |
||||
#define ACR_PCI_RPTCNT 0x00007000 /* PCI repeat count */ |
||||
#define ACR_PCI_RPTCNT_SHIFT (31-19) |
||||
#define ACR_RPTCNT 0x00000700 /* Repeat count */ |
||||
#define ACR_RPTCNT_SHIFT (31-23) |
||||
#define ACR_APARK 0x00000030 /* Address parking */ |
||||
#define ACR_APARK_SHIFT (31-27) |
||||
#define ACR_PARKM 0x0000000F /* Parking master */ |
||||
#define ACR_PARKM_SHIFT (31-31) |
||||
|
||||
/* ATR - Arbiter Timers Register
|
||||
*/ |
||||
#define ATR_DTO 0x00FF0000 /* Data time out */ |
||||
#define ATR_ATO 0x000000FF /* Address time out */ |
||||
|
||||
/* AER - Arbiter Event Register
|
||||
*/ |
||||
#define AER_ETEA 0x00000020 /* Transfer error */ |
||||
#define AER_RES 0x00000010 /* Reserved transfer type */ |
||||
#define AER_ECW 0x00000008 /* External control word transfer type */ |
||||
#define AER_AO 0x00000004 /* Address Only transfer type */ |
||||
#define AER_DTO 0x00000002 /* Data time out */ |
||||
#define AER_ATO 0x00000001 /* Address time out */ |
||||
|
||||
/* AEATR - Arbiter Event Address Register
|
||||
*/ |
||||
#define AEATR_EVENT 0x07000000 /* Event type */ |
||||
#define AEATR_MSTR_ID 0x001F0000 /* Master Id */ |
||||
#define AEATR_TBST 0x00000800 /* Transfer burst */ |
||||
#define AEATR_TSIZE 0x00000700 /* Transfer Size */ |
||||
#define AEATR_TTYPE 0x0000001F /* Transfer Type */ |
||||
|
||||
/* RSR - Reset Status Register
|
||||
*/ |
||||
#define RSR_SWSR 0x00002000 /* software soft reset */ |
||||
#define RSR_SWSR_SHIFT 13 |
||||
#define RSR_SWHR 0x00001000 /* software hard reset */ |
||||
#define RSR_SWHR_SHIFT 12 |
||||
#define RSR_JHRS 0x00000200 /* jtag hreset */ |
||||
#define RSR_JHRS_SHIFT 9 |
||||
#define RSR_JSRS 0x00000100 /* jtag sreset status */ |
||||
#define RSR_JSRS_SHIFT 8 |
||||
#define RSR_CSHR 0x00000010 /* checkstop reset status */ |
||||
#define RSR_CSHR_SHIFT 4 |
||||
#define RSR_SWRS 0x00000008 /* software watchdog reset status */ |
||||
#define RSR_SWRS_SHIFT 3 |
||||
#define RSR_BMRS 0x00000004 /* bus monitop reset status */ |
||||
#define RSR_BMRS_SHIFT 2 |
||||
#define RSR_SRS 0x00000002 /* soft reset status */ |
||||
#define RSR_SRS_SHIFT 1 |
||||
#define RSR_HRS 0x00000001 /* hard reset status */ |
||||
#define RSR_HRS_SHIFT 0 |
||||
#define RSR_RES ~(RSR_SWSR | RSR_SWHR |\ |
||||
RSR_JHRS | RSR_JSRS | RSR_CSHR | RSR_SWRS |\
|
||||
RSR_BMRS | RSR_SRS | RSR_HRS) |
||||
/* RMR - Reset Mode Register
|
||||
*/ |
||||
#define RMR_CSRE 0x00000001 /* checkstop reset enable */ |
||||
#define RMR_CSRE_SHIFT 0 |
||||
#define RMR_RES ~(RMR_CSRE) |
||||
|
||||
/* RCR - Reset Control Register
|
||||
*/ |
||||
#define RCR_SWHR 0x00000002 /* software hard reset */ |
||||
#define RCR_SWSR 0x00000001 /* software soft reset */ |
||||
#define RCR_RES ~(RCR_SWHR | RCR_SWSR) |
||||
|
||||
/* RCER - Reset Control Enable Register
|
||||
*/ |
||||
#define RCER_CRE 0x00000001 /* software hard reset */ |
||||
#define RCER_RES ~(RCER_CRE) |
||||
|
||||
/* SPMR - System PLL Mode Register
|
||||
*/ |
||||
#define SPMR_SPMF 0x0F000000 |
||||
#define SPMR_SPMF_SHIFT 24 |
||||
#define SPMR_CPMF 0x000F0000 |
||||
#define SPMR_CPMF_SHIFT 16 |
||||
|
||||
/* SCFR1 System Clock Frequency Register 1
|
||||
*/ |
||||
#define SCFR1_IPS_DIV 0x2 |
||||
#define SCFR1_IPS_DIV_MASK 0x03800000 |
||||
#define SCFR1_IPS_DIV_SHIFT 23 |
||||
|
||||
/* SCFR2 System Clock Frequency Register 2
|
||||
*/ |
||||
#define SCFR2_SYS_DIV 0xFC000000 |
||||
#define SCFR2_SYS_DIV_SHIFT 26 |
||||
|
||||
/* SCCR - System Clock Control Registers
|
||||
*/ |
||||
|
||||
/* System Clock Control Register 1 commands */ |
||||
#define CLOCK_SCCR1_CFG_EN 0x80000000 |
||||
#define CLOCK_SCCR1_LPC_EN 0x40000000 |
||||
#define CLOCK_SCCR1_NFC_EN 0x20000000 |
||||
#define CLOCK_SCCR1_PATA_EN 0x10000000 |
||||
#define CLOCK_SCCR1_PSC_EN(cn) (0x08000000 >> (cn)) |
||||
#define CLOCK_SCCR1_PSCFIFO_EN 0x00008000 |
||||
#define CLOCK_SCCR1_SATA_EN 0x00004000 |
||||
#define CLOCK_SCCR1_FEC_EN 0x00002000 |
||||
#define CLOCK_SCCR1_TPR_EN 0x00001000 |
||||
#define CLOCK_SCCR1_PCI_EN 0x00000800 |
||||
#define CLOCK_SCCR1_DDR_EN 0x00000400 |
||||
|
||||
/* System Clock Control Register 2 commands */ |
||||
#define CLOCK_SCCR2_DIU_EN 0x80000000 |
||||
#define CLOCK_SCCR2_AXE_EN 0x40000000 |
||||
#define CLOCK_SCCR2_MEM_EN 0x20000000 |
||||
#define CLOCK_SCCR2_USB2_EN 0x10000000 |
||||
#define CLOCK_SCCR2_USB1_EN 0x08000000 |
||||
#define CLOCK_SCCR2_I2C_EN 0x04000000 |
||||
#define CLOCK_SCCR2_BDLC_EN 0x02000000 |
||||
#define CLOCK_SCCR2_SDHC_EN 0x01000000 |
||||
#define CLOCK_SCCR2_SPDIF_EN 0x00800000 |
||||
#define CLOCK_SCCR2_MBX_BUS_EN 0x00400000 |
||||
#define CLOCK_SCCR2_MBX_EN 0x00200000 |
||||
#define CLOCK_SCCR2_MBX_3D_EN 0x00100000 |
||||
#define CLOCK_SCCR2_IIM_EN 0x00080000 |
||||
|
||||
/* PSC FIFO Command values */ |
||||
#define PSC_FIFO_RESET_SLICE 0x80 |
||||
#define PSC_FIFO_ENABLE_SLICE 0x01 |
||||
|
||||
/* PSC FIFO Controller Command values */ |
||||
#define FIFOC_ENABLE_CLOCK_GATE 0x01 |
||||
#define FIFOC_DISABLE_CLOCK_GATE 0x00 |
||||
|
||||
/* PSC FIFO status */ |
||||
#define PSC_FIFO_EMPTY 0x01 |
||||
|
||||
/* PSC Command values */ |
||||
#define PSC_RX_ENABLE 0x01 |
||||
#define PSC_RX_DISABLE 0x02 |
||||
#define PSC_TX_ENABLE 0x04 |
||||
#define PSC_TX_DISABLE 0x08 |
||||
#define PSC_SEL_MODE_REG_1 0x10 |
||||
#define PSC_RST_RX 0x20 |
||||
#define PSC_RST_TX 0x30 |
||||
#define PSC_RST_ERR_STAT 0x40 |
||||
#define PSC_RST_BRK_CHG_INT 0x50 |
||||
#define PSC_START_BRK 0x60 |
||||
#define PSC_STOP_BRK 0x70 |
||||
|
||||
/* PSC status register bits */ |
||||
#define PSC_SR_CDE 0x0080 |
||||
#define PSC_SR_TXEMP 0x0800 |
||||
#define PSC_SR_OE 0x1000 |
||||
#define PSC_SR_PE 0x2000 |
||||
#define PSC_SR_FE 0x4000 |
||||
#define PSC_SR_RB 0x8000 |
||||
|
||||
/* PSC mode fields */ |
||||
#define PSC_MODE_5_BITS 0x00 |
||||
#define PSC_MODE_6_BITS 0x01 |
||||
#define PSC_MODE_7_BITS 0x02 |
||||
#define PSC_MODE_8_BITS 0x03 |
||||
#define PSC_MODE_PAREVEN 0x00 |
||||
#define PSC_MODE_PARODD 0x04 |
||||
#define PSC_MODE_PARFORCE 0x08 |
||||
#define PSC_MODE_PARNONE 0x10 |
||||
#define PSC_MODE_ENTIMEOUT 0x20 |
||||
#define PSC_MODE_RXRTS 0x80 |
||||
#define PSC_MODE_1_STOPBIT 0x07 |
||||
|
||||
/*
|
||||
* Centralized FIFO Controller has internal memory for all 12 PSCs FIFOs |
||||
* |
||||
* NOTE: individual PSC units are free to use whatever area (and size) of the |
||||
* FIFOC internal memory, so make sure memory areas for FIFO slices used by |
||||
* different PSCs do not overlap! |
||||
* |
||||
* Overall size of FIFOC memory is not documented in the MPC5121e RM, but |
||||
* tests indicate that it is 1024 words total. |
||||
*/ |
||||
#define FIFOC_PSC0_TX_SIZE 0x0 /* number of 4-byte words for FIFO slice */ |
||||
#define FIFOC_PSC0_TX_ADDR 0x0 |
||||
#define FIFOC_PSC0_RX_SIZE 0x0 |
||||
#define FIFOC_PSC0_RX_ADDR 0x0 |
||||
|
||||
#define FIFOC_PSC1_TX_SIZE 0x0 |
||||
#define FIFOC_PSC1_TX_ADDR 0x0 |
||||
#define FIFOC_PSC1_RX_SIZE 0x0 |
||||
#define FIFOC_PSC1_RX_ADDR 0x0 |
||||
|
||||
#define FIFOC_PSC2_TX_SIZE 0x0 |
||||
#define FIFOC_PSC2_TX_ADDR 0x0 |
||||
#define FIFOC_PSC2_RX_SIZE 0x0 |
||||
#define FIFOC_PSC2_RX_ADDR 0x0 |
||||
|
||||
#define FIFOC_PSC3_TX_SIZE 0x04 |
||||
#define FIFOC_PSC3_TX_ADDR 0x0 |
||||
#define FIFOC_PSC3_RX_SIZE 0x04 |
||||
#define FIFOC_PSC3_RX_ADDR 0x10 |
||||
|
||||
#define FIFOC_PSC4_TX_SIZE 0x0 |
||||
#define FIFOC_PSC4_TX_ADDR 0x0 |
||||
#define FIFOC_PSC4_RX_SIZE 0x0 |
||||
#define FIFOC_PSC4_RX_ADDR 0x0 |
||||
|
||||
#define FIFOC_PSC5_TX_SIZE 0x0 |
||||
#define FIFOC_PSC5_TX_ADDR 0x0 |
||||
#define FIFOC_PSC5_RX_SIZE 0x0 |
||||
#define FIFOC_PSC5_RX_ADDR 0x0 |
||||
|
||||
#define FIFOC_PSC6_TX_SIZE 0x0 |
||||
#define FIFOC_PSC6_TX_ADDR 0x0 |
||||
#define FIFOC_PSC6_RX_SIZE 0x0 |
||||
#define FIFOC_PSC6_RX_ADDR 0x0 |
||||
|
||||
#define FIFOC_PSC7_TX_SIZE 0x0 |
||||
#define FIFOC_PSC7_TX_ADDR 0x0 |
||||
#define FIFOC_PSC7_RX_SIZE 0x0 |
||||
#define FIFOC_PSC7_RX_ADDR 0x0 |
||||
|
||||
#define FIFOC_PSC8_TX_SIZE 0x0 |
||||
#define FIFOC_PSC8_TX_ADDR 0x0 |
||||
#define FIFOC_PSC8_RX_SIZE 0x0 |
||||
#define FIFOC_PSC8_RX_ADDR 0x0 |
||||
|
||||
#define FIFOC_PSC9_TX_SIZE 0x0 |
||||
#define FIFOC_PSC9_TX_ADDR 0x0 |
||||
#define FIFOC_PSC9_RX_SIZE 0x0 |
||||
#define FIFOC_PSC9_RX_ADDR 0x0 |
||||
|
||||
#define FIFOC_PSC10_TX_SIZE 0x0 |
||||
#define FIFOC_PSC10_TX_ADDR 0x0 |
||||
#define FIFOC_PSC10_RX_SIZE 0x0 |
||||
#define FIFOC_PSC10_RX_ADDR 0x0 |
||||
|
||||
#define FIFOC_PSC11_TX_SIZE 0x0 |
||||
#define FIFOC_PSC11_TX_ADDR 0x0 |
||||
#define FIFOC_PSC11_RX_SIZE 0x0 |
||||
#define FIFOC_PSC11_RX_ADDR 0x0 |
||||
|
||||
/* IO Control Register
|
||||
*/ |
||||
|
||||
/* Indexes in regs array */ |
||||
#define MEM_IDX 0x00 |
||||
#define SPDIF_TXCLOCK_IDX 0x73 |
||||
#define SPDIF_TX_IDX 0x74 |
||||
#define SPDIF_RX_IDX 0x75 |
||||
#define PSC0_0_IDX 0x83 |
||||
#define PSC0_1_IDX 0x84 |
||||
#define PSC0_2_IDX 0x85 |
||||
#define PSC0_3_IDX 0x86 |
||||
#define PSC0_4_IDX 0x87 |
||||
#define PSC1_0_IDX 0x88 |
||||
#define PSC1_1_IDX 0x89 |
||||
#define PSC1_2_IDX 0x8a |
||||
#define PSC1_3_IDX 0x8b |
||||
#define PSC1_4_IDX 0x8c |
||||
#define PSC2_0_IDX 0x8d |
||||
#define PSC2_1_IDX 0x8e |
||||
#define PSC2_2_IDX 0x8f |
||||
#define PSC2_3_IDX 0x90 |
||||
#define PSC2_4_IDX 0x91 |
||||
|
||||
#define IOCTRL_FUNCMUX_SHIFT 7 |
||||
#define IOCTRL_FUNCMUX_FEC 1 |
||||
#define IOCTRL_MUX_FEC (IOCTRL_FUNCMUX_FEC << IOCTRL_FUNCMUX_SHIFT) |
||||
|
||||
/* Set for DDR */ |
||||
#define IOCTRL_MUX_DDR 0x00000036 |
||||
|
||||
/* Register Offset Base */ |
||||
#define MPC512X_FEC (CFG_IMMR + 0x02800) |
||||
|
||||
/* Number of I2C buses */ |
||||
#define I2C_BUS_CNT 3 |
||||
|
||||
/* I2Cn control register bits */ |
||||
#define I2C_EN 0x80 |
||||
#define I2C_IEN 0x40 |
||||
#define I2C_STA 0x20 |
||||
#define I2C_TX 0x10 |
||||
#define I2C_TXAK 0x08 |
||||
#define I2C_RSTA 0x04 |
||||
#define I2C_INIT_MASK (I2C_EN | I2C_STA | I2C_TX | I2C_RSTA) |
||||
|
||||
/* I2Cn status register bits */ |
||||
#define I2C_CF 0x80 |
||||
#define I2C_AAS 0x40 |
||||
#define I2C_BB 0x20 |
||||
#define I2C_AL 0x10 |
||||
#define I2C_SRW 0x04 |
||||
#define I2C_IF 0x02 |
||||
#define I2C_RXAK 0x01 |
||||
|
||||
#endif /* __MPC512X_H__ */ |
Loading…
Reference in new issue